Repository: cloudwego/hertz
Pull request #742 (2023-04-21 07:22:57)

feat(hz): compatibility annotations for protobuf
#### What type of PR is this?
<!--
Add one of the following kinds:

build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
docs: Documentation only changes
feat: A new feature
optimize: A new optimization
fix: A bug fix
perf: A code change that improves performance
refactor: A code change that neither fixes a bug nor adds a feature
style: Changes that do not affect the meaning of the code (white space, formatting, missing semi-colons, etc)
test: Adding missing tests or correcting existing tests
chore: Changes to the build process or auxiliary tools and libraries such as documentation generation
-->
feat
#### Check the PR title.
<!--
The description of the title will be attached in Release Notes, 
so please describe it from user-oriented, what this PR does / why we need it.
Please check your PR title with the below requirements:
-->
- [x] This PR title match the format: `<type>(optional scope): <description>`.
- [x] The description of this PR title is user-oriented and clear enough for others to understand.
- [x] Attach the PR updating the user documentation if the current PR requires user awareness at the usage level. [User docs repo](https://github.com/cloudwego/cloudwego.github.io).

#### (Optional) Translate the PR title into Chinese.
为 protobuf 添加兼容性注解

#### (Optional) More detail description for this PR(en: English/zh: Chinese).
<!--
Provide more detailed info for review. If it is a perf type PR, perf data is suggested to give.
-->
en:  Add compatibility annotations to protobuf to avoid serial number conflicts
zh(optional): 为 protobuf 添加兼容性注解，避免出现序号冲突

#### (Optional) Which issue(s) this PR fixes:
<!--
Automatically closes linked issue when PR is merged.
Eg: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
-->

#### (Optional) The PR that updates user documentation:
<!--
If the current PR requires user awareness at the usage level, please submit a PR to update user docs. [User docs repo](https://github.com/cloudwego/cloudwego.github.io)
-->
https://github.com/cloudwego/cloudwego.github.io/pull/621/commits

codecov[bot]: ## [Codecov](https://codecov.io/gh/cloudwego/hertz/pull/742?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego) Report
Patch coverage has no change and project coverage change: **`+0.07`** :tada:
> Comparison is base [(`65b5207`)](https://codecov.io/gh/cloudwego/hertz/commit/65b5207e27827e8136bf32c65a600b55f04e4af1?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego) 75.64% compared to head [(`0eb0329`)](https://codecov.io/gh/cloudwego/hertz/pull/742?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego) 75.72%.

> :exclamation: Current head 0eb0329 differs from pull request most recent head 449c66d. Consider uploading reports for the commit 449c66d to get more accurate results

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff             @@
##           develop     #742      +/-   ##
===========================================
+ Coverage    75.64%   75.72%   +0.07%     
===========================================
  Files           97       97              
  Lines         9462     9462              
===========================================
+ Hits          7158     7165       +7     
+ Misses        1855     1849       -6     
+ Partials       449      448       -1     
```


[see 1 file with indirect coverage changes](https://codecov.io/gh/cloudwego/hertz/pull/742/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego)

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego)

</details>

[:umbrella: View full report in Codecov by Sentry](https://codecov.io/gh/cloudwego/hertz/pull/742?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=cloudwego).


Patch:
diff --git a/cmd/hz/protobuf/api/api.pb.go b/cmd/hz/protobuf/api/api.pb.go
index 6a38b1b..929f9a2 100644
--- a/cmd/hz/protobuf/api/api.pb.go
+++ b/cmd/hz/protobuf/api/api.pb.go
@@ -1,17 +1,16 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
 // 	protoc-gen-go v1.28.1
-// 	protoc        v3.19.4
+// 	protoc        v3.21.12
 // source: api.proto
 
 package api
 
 import (
-	reflect "reflect"
-
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
 	descriptorpb "google.golang.org/protobuf/types/descriptorpb"
+	reflect "reflect"
 )
 
 const (
@@ -86,14 +85,6 @@ var file_api_proto_extTypes = []protoimpl.ExtensionInfo{
 		Tag:           "bytes,50108,opt,name=form",
 		Filename:      "api.proto",
 	},
-	{
-		ExtendedType:  (*descriptorpb.FieldOptions)(nil),
-		ExtensionType: (*string)(nil),
-		Field:         51001,
-		Name:          "api.go_tag",
-		Tag:           "bytes,51001,opt,name=go_tag",
-		Filename:      "api.proto",
-	},
 	{
 		ExtendedType:  (*descriptorpb.FieldOptions)(nil),
 		ExtensionType: (*string)(nil),
@@ -110,6 +101,38 @@ var file_api_proto_extTypes = []protoimpl.ExtensionInfo{
 		Tag:           "bytes,50110,opt,name=file_name",
 		Filename:      "api.proto",
 	},
+	{
+		ExtendedType:  (*descriptorpb.FieldOptions)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         50131,
+		Name:          "api.form_compatible",
+		Tag:           "bytes,50131,opt,name=form_compatible",
+		Filename:      "api.proto",
+	},
+	{
+		ExtendedType:  (*descriptorpb.FieldOptions)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         50132,
+		Name:          "api.js_conv_compatible",
+		Tag:           "bytes,50132,opt,name=js_conv_compatible",
+		Filename:      "api.proto",
+	},
+	{
+		ExtendedType:  (*descriptorpb.FieldOptions)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         50133,
+		Name:          "api.file_name_compatible",
+		Tag:           "bytes,50133,opt,name=file_name_compatible",
+		Filename:      "api.proto",
+	},
+	{
+		ExtendedType:  (*descriptorpb.FieldOptions)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         51001,
+		Name:          "api.go_tag",
+		Tag:           "bytes,51001,opt,name=go_tag",
+		Filename:      "api.proto",
+	},
 	{
 		ExtendedType:  (*descriptorpb.MethodOptions)(nil),
 		ExtensionType: (*string)(nil),
@@ -246,6 +269,14 @@ var file_api_proto_extTypes = []protoimpl.ExtensionInfo{
 		Tag:           "bytes,50309,opt,name=handler_path",
 		Filename:      "api.proto",
 	},
+	{
+		ExtendedType:  (*descriptorpb.MethodOptions)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         50331,
+		Name:          "api.handler_path_compatible",
+		Tag:           "bytes,50331,opt,name=handler_path_compatible",
+		Filename:      "api.proto",
+	},
 	{
 		ExtendedType:  (*descriptorpb.EnumValueOptions)(nil),
 		ExtensionType: (*int32)(nil),
@@ -262,6 +293,14 @@ var file_api_proto_extTypes = []protoimpl.ExtensionInfo{
 		Tag:           "bytes,50402,opt,name=base_domain",
 		Filename:      "api.proto",
 	},
+	{
+		ExtendedType:  (*descriptorpb.ServiceOptions)(nil),
+		ExtensionType: (*string)(nil),
+		Field:         50731,
+		Name:          "api.base_domain_compatible",
+		Tag:           "bytes,50731,opt,name=base_domain_compatible",
+		Filename:      "api.proto",
+	},
 }
 
 // Extension fields to descriptorpb.FieldOptions.
@@ -282,62 +321,78 @@ var (
 	E_Vd = &file_api_proto_extTypes[6]
 	// optional string form = 50108;
 	E_Form = &file_api_proto_extTypes[7]
-	// optional string go_tag = 51001;
-	E_GoTag = &file_api_proto_extTypes[8]
 	// optional string js_conv = 50109;
-	E_JsConv = &file_api_proto_extTypes[9]
+	E_JsConv = &file_api_proto_extTypes[8]
 	// optional string file_name = 50110;
-	E_FileName = &file_api_proto_extTypes[10]
+	E_FileName = &file_api_proto_extTypes[9]
+	// 50131~50160 used to extend field option by hz
+	//
+	// optional string form_compatible = 50131;
+	E_FormCompatible = &file_api_proto_extTypes[10]
+	// optional string js_conv_compatible = 50132;
+	E_JsConvCompatible = &file_api_proto_extTypes[11]
+	// optional string file_name_compatible = 50133;
+	E_FileNameCompatible = &file_api_proto_extTypes[12]
+	// optional string go_tag = 51001;
+	E_GoTag = &file_api_proto_extTypes[13]
 )
 
 // Extension fields to descriptorpb.MethodOptions.
 var (
 	// optional string get = 50201;
-	E_Get = &file_api_proto_extTypes[11]
+	E_Get = &file_api_proto_extTypes[14]
 	// optional string post = 50202;
-	E_Post = &file_api_proto_extTypes[12]
+	E_Post = &file_api_proto_extTypes[15]
 	// optional string put = 50203;
-	E_Put = &file_api_proto_extTypes[13]
+	E_Put = &file_api_proto_extTypes[16]
 	// optional string delete = 50204;
-	E_Delete = &file_api_proto_extTypes[14]
+	E_Delete = &file_api_proto_extTypes[17]
 	// optional string patch = 50205;
-	E_Patch = &file_api_proto_extTypes[15]
+	E_Patch = &file_api_proto_extTypes[18]
 	// optional string options = 50206;
-	E_Options = &file_api_proto_extTypes[16]
+	E_Options = &file_api_proto_extTypes[19]
 	// optional string head = 50207;
-	E_Head = &file_api_proto_extTypes[17]
+	E_Head = &file_api_proto_extTypes[20]
 	// optional string any = 50208;
-	E_Any = &file_api_proto_extTypes[18]
+	E_Any = &file_api_proto_extTypes[21]
 	// optional string gen_path = 50301;
-	E_GenPath = &file_api_proto_extTypes[19] // The path specified by the user when the client code is generated, with a higher priority than api_version
+	E_GenPath = &file_api_proto_extTypes[22] // The path specified by the user when the client code is generated, with a higher priority than api_version
 	// optional string api_version = 50302;
-	E_ApiVersion = &file_api_proto_extTypes[20] // Specify the value of the :version variable in path when the client code is generated
+	E_ApiVersion = &file_api_proto_extTypes[23] // Specify the value of the :version variable in path when the client code is generated
 	// optional string tag = 50303;
-	E_Tag = &file_api_proto_extTypes[21] // rpc tag, can be multiple, separated by commas
+	E_Tag = &file_api_proto_extTypes[24] // rpc tag, can be multiple, separated by commas
 	// optional string name = 50304;
-	E_Name = &file_api_proto_extTypes[22] // Name of rpc
+	E_Name = &file_api_proto_extTypes[25] // Name of rpc
 	// optional string api_level = 50305;
-	E_ApiLevel = &file_api_proto_extTypes[23] // Interface Level
+	E_ApiLevel = &file_api_proto_extTypes[26] // Interface Level
 	// optional string serializer = 50306;
-	E_Serializer = &file_api_proto_extTypes[24] // Serialization method
+	E_Serializer = &file_api_proto_extTypes[27] // Serialization method
 	// optional string param = 50307;
-	E_Param = &file_api_proto_extTypes[25] // Whether client requests take public parameters
+	E_Param = &file_api_proto_extTypes[28] // Whether client requests take public parameters
 	// optional string baseurl = 50308;
-	E_Baseurl = &file_api_proto_extTypes[26] // Baseurl used in ttnet routing
+	E_Baseurl = &file_api_proto_extTypes[29] // Baseurl used in ttnet routing
 	// optional string handler_path = 50309;
-	E_HandlerPath = &file_api_proto_extTypes[27] // handler_path specifies the path to generate the method
+	E_HandlerPath = &file_api_proto_extTypes[30] // handler_path specifies the path to generate the method
+	// 50331~50360 used to extend method option by hz
+	//
+	// optional string handler_path_compatible = 50331;
+	E_HandlerPathCompatible = &file_api_proto_extTypes[31] // handler_path specifies the path to generate the method
 )
 
 // Extension fields to descriptorpb.EnumValueOptions.
 var (
 	// optional int32 http_code = 50401;
-	E_HttpCode = &file_api_proto_extTypes[28]
+	E_HttpCode = &file_api_proto_extTypes[32]
 )
 
 // Extension fields to descriptorpb.ServiceOptions.
 var (
 	// optional string base_domain = 50402;
-	E_BaseDomain = &file_api_proto_extTypes[29]
+	E_BaseDomain = &file_api_proto_extTypes[33]
+	// 50731~50760 used to extend service option by hz
+	//
+	// optional string base_domain_compatible = 50731;
+	E_BaseDomainCompatible = &file_api_proto_extTypes[34]
 )
 
 var File_api_proto protoreflect.FileDescriptor
@@ -373,88 +428,114 @@ var file_api_proto_rawDesc = []byte{
 	0x76, 0x64, 0x3a, 0x33, 0x0a, 0x04, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f,
 	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65,
 	0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xbc, 0x87, 0x03, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x04, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x36, 0x0a, 0x06, 0x67, 0x6f, 0x5f, 0x74, 0x61,
-	0x67, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
-	0x18, 0xb9, 0x8e, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x6f, 0x54, 0x61, 0x67, 0x3a,
-	0x38, 0x0a, 0x07, 0x6a, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x76, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f,
-	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65,
-	0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xbd, 0x87, 0x03, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x06, 0x6a, 0x73, 0x43, 0x6f, 0x6e, 0x76, 0x3a, 0x3c, 0x0a, 0x09, 0x66, 0x69, 0x6c,
-	0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70,
-	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xbe, 0x87, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66,
-	0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x3a, 0x32, 0x0a, 0x03, 0x67, 0x65, 0x74, 0x12, 0x1e,
+	0x09, 0x52, 0x04, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x38, 0x0a, 0x07, 0x6a, 0x73, 0x5f, 0x63, 0x6f,
+	0x6e, 0x76, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	0x73, 0x18, 0xbd, 0x87, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6a, 0x73, 0x43, 0x6f, 0x6e,
+	0x76, 0x3a, 0x3c, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d,
 	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
-	0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x99,
-	0x88, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x67, 0x65, 0x74, 0x3a, 0x34, 0x0a, 0x04, 0x70,
-	0x6f, 0x73, 0x74, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69,
-	0x6f, 0x6e, 0x73, 0x18, 0x9a, 0x88, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x73,
-	0x74, 0x3a, 0x32, 0x0a, 0x03, 0x70, 0x75, 0x74, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
-	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f,
-	0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x9b, 0x88, 0x03, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x03, 0x70, 0x75, 0x74, 0x3a, 0x38, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12,
+	0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xbe, 0x87,
+	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x3a,
+	0x48, 0x0a, 0x0f, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62,
+	0x6c, 0x65, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	0x73, 0x18, 0xd3, 0x87, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x66, 0x6f, 0x72, 0x6d, 0x43,
+	0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x3a, 0x4d, 0x0a, 0x12, 0x6a, 0x73, 0x5f,
+	0x63, 0x6f, 0x6e, 0x76, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x12,
+	0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd4,
+	0x87, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6a, 0x73, 0x43, 0x6f, 0x6e, 0x76, 0x43, 0x6f,
+	0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x3a, 0x51, 0x0a, 0x14, 0x66, 0x69, 0x6c, 0x65,
+	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65,
+	0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+	0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
+	0xd5, 0x87, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d,
+	0x65, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x3a, 0x36, 0x0a, 0x06, 0x67,
+	0x6f, 0x5f, 0x74, 0x61, 0x67, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74,
+	0x69, 0x6f, 0x6e, 0x73, 0x18, 0xb9, 0x8e, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, 0x6f,
+	0x54, 0x61, 0x67, 0x3a, 0x32, 0x0a, 0x03, 0x67, 0x65, 0x74, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f,
+	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74,
+	0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x99, 0x88, 0x03, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x03, 0x67, 0x65, 0x74, 0x3a, 0x34, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x12,
 	0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
 	0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
-	0x9c, 0x88, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x3a,
-	0x36, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
-	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f,
-	0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x9d, 0x88, 0x03, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x3a, 0x3a, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f,
-	0x6e, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f,
-	0x6e, 0x73, 0x18, 0x9e, 0x88, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69,
-	0x6f, 0x6e, 0x73, 0x3a, 0x34, 0x0a, 0x04, 0x68, 0x65, 0x61, 0x64, 0x12, 0x1e, 0x2e, 0x67, 0x6f,
-	0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65,
-	0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x9f, 0x88, 0x03, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x65, 0x61, 0x64, 0x3a, 0x32, 0x0a, 0x03, 0x61, 0x6e, 0x79,
-	0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
-	0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
-	0x18, 0xa0, 0x88, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x6e, 0x79, 0x3a, 0x3b, 0x0a,
-	0x08, 0x67, 0x65, 0x6e, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
-	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68,
-	0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xfd, 0x88, 0x03, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x07, 0x67, 0x65, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x3a, 0x41, 0x0a, 0x0b, 0x61, 0x70,
-	0x69, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
-	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68,
-	0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xfe, 0x88, 0x03, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0a, 0x61, 0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x32, 0x0a,
-	0x03, 0x74, 0x61, 0x67, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x73, 0x18, 0xff, 0x88, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61,
-	0x67, 0x3a, 0x34, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
-	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68,
-	0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x80, 0x89, 0x03, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x3d, 0x0a, 0x09, 0x61, 0x70, 0x69, 0x5f, 0x6c,
-	0x65, 0x76, 0x65, 0x6c, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+	0x9a, 0x88, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x3a, 0x32, 0x0a,
+	0x03, 0x70, 0x75, 0x74, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
 	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x73, 0x18, 0x81, 0x89, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70,
-	0x69, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x3a, 0x40, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c,
-	0x69, 0x7a, 0x65, 0x72, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x73, 0x18, 0x82, 0x89, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65,
-	0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x3a, 0x36, 0x0a, 0x05, 0x70, 0x61, 0x72, 0x61,
-	0x6d, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
-	0x73, 0x18, 0x83, 0x89, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x72, 0x61, 0x6d,
-	0x3a, 0x3a, 0x0a, 0x07, 0x62, 0x61, 0x73, 0x65, 0x75, 0x72, 0x6c, 0x12, 0x1e, 0x2e, 0x67, 0x6f,
+	0x69, 0x6f, 0x6e, 0x73, 0x18, 0x9b, 0x88, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x75,
+	0x74, 0x3a, 0x38, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1e, 0x2e, 0x67, 0x6f,
 	0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65,
-	0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x84, 0x89, 0x03, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x61, 0x73, 0x65, 0x75, 0x72, 0x6c, 0x3a, 0x43, 0x0a, 0x0c,
-	0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1e, 0x2e, 0x67,
-	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d,
-	0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x85, 0x89, 0x03,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x50, 0x61, 0x74,
-	0x68, 0x3a, 0x40, 0x0a, 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x21,
+	0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x9c, 0x88, 0x03, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x3a, 0x36, 0x0a, 0x05, 0x70,
+	0x61, 0x74, 0x63, 0x68, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74,
+	0x69, 0x6f, 0x6e, 0x73, 0x18, 0x9d, 0x88, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61,
+	0x74, 0x63, 0x68, 0x3a, 0x3a, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e,
 	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
-	0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
-	0x73, 0x18, 0xe1, 0x89, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x68, 0x74, 0x74, 0x70, 0x43,
-	0x6f, 0x64, 0x65, 0x3a, 0x42, 0x0a, 0x0b, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x64, 0x6f, 0x6d, 0x61,
-	0x69, 0x6e, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x74, 0x69,
-	0x6f, 0x6e, 0x73, 0x18, 0xe2, 0x89, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x61, 0x73,
-	0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x42, 0x06, 0x5a, 0x04, 0x2f, 0x61, 0x70, 0x69,
+	0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x9e,
+	0x88, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a,
+	0x34, 0x0a, 0x04, 0x68, 0x65, 0x61, 0x64, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64,
+	0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x9f, 0x88, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x04, 0x68, 0x65, 0x61, 0x64, 0x3a, 0x32, 0x0a, 0x03, 0x61, 0x6e, 0x79, 0x12, 0x1e, 0x2e, 0x67,
+	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d,
+	0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xa0, 0x88, 0x03,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x6e, 0x79, 0x3a, 0x3b, 0x0a, 0x08, 0x67, 0x65, 0x6e,
+	0x5f, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70,
+	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xfd, 0x88, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67,
+	0x65, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x3a, 0x41, 0x0a, 0x0b, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x65,
+	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70,
+	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xfe, 0x88, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61,
+	0x70, 0x69, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x32, 0x0a, 0x03, 0x74, 0x61, 0x67,
+	0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+	0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+	0x18, 0xff, 0x88, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x3a, 0x34, 0x0a,
+	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70,
+	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x80, 0x89, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x3a, 0x3d, 0x0a, 0x09, 0x61, 0x70, 0x69, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c,
+	0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+	0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+	0x18, 0x81, 0x89, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x69, 0x4c, 0x65, 0x76,
+	0x65, 0x6c, 0x3a, 0x40, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72,
+	0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+	0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+	0x18, 0x82, 0x89, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c,
+	0x69, 0x7a, 0x65, 0x72, 0x3a, 0x36, 0x0a, 0x05, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x1e, 0x2e,
+	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
+	0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x83, 0x89,
+	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x3a, 0x3a, 0x0a, 0x07,
+	0x62, 0x61, 0x73, 0x65, 0x75, 0x72, 0x6c, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64,
+	0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x84, 0x89, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x07, 0x62, 0x61, 0x73, 0x65, 0x75, 0x72, 0x6c, 0x3a, 0x43, 0x0a, 0x0c, 0x68, 0x61, 0x6e, 0x64,
+	0x6c, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f,
+	0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x85, 0x89, 0x03, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x0b, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x50, 0x61, 0x74, 0x68, 0x3a, 0x58, 0x0a,
+	0x17, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x63, 0x6f,
+	0x6d, 0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f,
+	0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x9b, 0x89, 0x03, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x15, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x50, 0x61, 0x74, 0x68, 0x43, 0x6f, 0x6d,
+	0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x3a, 0x40, 0x0a, 0x09, 0x68, 0x74, 0x74, 0x70, 0x5f,
+	0x63, 0x6f, 0x64, 0x65, 0x12, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65,
+	0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xe1, 0x89, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52,
+	0x08, 0x68, 0x74, 0x74, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x3a, 0x42, 0x0a, 0x0b, 0x62, 0x61, 0x73,
+	0x65, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xe2, 0x89, 0x03, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x0a, 0x62, 0x61, 0x73, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x3a, 0x57, 0x0a,
+	0x16, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6d,
+	0x70, 0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xab, 0x8c, 0x03, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x14, 0x62, 0x61, 0x73, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6d, 0x70,
+	0x61, 0x74, 0x69, 0x62, 0x6c, 0x65, 0x42, 0x06, 0x5a, 0x04, 0x2f, 0x61, 0x70, 0x69,
 }
 
 var file_api_proto_goTypes = []interface{}{
@@ -472,32 +553,37 @@ var file_api_proto_depIdxs = []int32{
 	0,  // 5: api.path:extendee -> google.protobuf.FieldOptions
 	0,  // 6: api.vd:extendee -> google.protobuf.FieldOptions
 	0,  // 7: api.form:extendee -> google.protobuf.FieldOptions
-	0,  // 8: api.go_tag:extendee -> google.protobuf.FieldOptions
-	0,  // 9: api.js_conv:extendee -> google.protobuf.FieldOptions
-	0,  // 10: api.file_name:extendee -> google.protobuf.FieldOptions
-	1,  // 11: api.get:extendee -> google.protobuf.MethodOptions
-	1,  // 12: api.post:extendee -> google.protobuf.MethodOptions
-	1,  // 13: api.put:extendee -> google.protobuf.MethodOptions
-	1,  // 14: api.delete:extendee -> google.protobuf.MethodOptions
-	1,  // 15: api.patch:extendee -> google.protobuf.MethodOptions
-	1,  // 16: api.options:extendee -> google.protobuf.MethodOptions
-	1,  // 17: api.head:extendee -> google.protobuf.MethodOptions
-	1,  // 18: api.any:extendee -> google.protobuf.MethodOptions
-	1,  // 19: api.gen_path:extendee -> google.protobuf.MethodOptions
-	1,  // 20: api.api_version:extendee -> google.protobuf.MethodOptions
-	1,  // 21: api.tag:extendee -> google.protobuf.MethodOptions
-	1,  // 22: api.name:extendee -> google.protobuf.MethodOptions
-	1,  // 23: api.api_level:extendee -> google.protobuf.MethodOptions
-	1,  // 24: api.serializer:extendee -> google.protobuf.MethodOptions
-	1,  // 25: api.param:extendee -> google.protobuf.MethodOptions
-	1,  // 26: api.baseurl:extendee -> google.protobuf.MethodOptions
-	1,  // 27: api.handler_path:extendee -> google.protobuf.MethodOptions
-	2,  // 28: api.http_code:extendee -> google.protobuf.EnumValueOptions
-	3,  // 29: api.base_domain:extendee -> google.protobuf.ServiceOptions
-	30, // [30:30] is the sub-list for method output_type
-	30, // [30:30] is the sub-list for method input_type
-	30, // [30:30] is the sub-list for extension type_name
-	0,  // [0:30] is the sub-list for extension extendee
+	0,  // 8: api.js_conv:extendee -> google.protobuf.FieldOptions
+	0,  // 9: api.file_name:extendee -> google.protobuf.FieldOptions
+	0,  // 10: api.form_compatible:extendee -> google.protobuf.FieldOptions
+	0,  // 11: api.js_conv_compatible:extendee -> google.protobuf.FieldOptions
+	0,  // 12: api.file_name_compatible:extendee -> google.protobuf.FieldOptions
+	0,  // 13: api.go_tag:extendee -> google.protobuf.FieldOptions
+	1,  // 14: api.get:extendee -> google.protobuf.MethodOptions
+	1,  // 15: api.post:extendee -> google.protobuf.MethodOptions
+	1,  // 16: api.put:extendee -> google.protobuf.MethodOptions
+	1,  // 17: api.delete:extendee -> google.protobuf.MethodOptions
+	1,  // 18: api.patch:extendee -> google.protobuf.MethodOptions
+	1,  // 19: api.options:extendee -> google.protobuf.MethodOptions
+	1,  // 20: api.head:extendee -> google.protobuf.MethodOptions
+	1,  // 21: api.any:extendee -> google.protobuf.MethodOptions
+	1,  // 22: api.gen_path:extendee -> google.protobuf.MethodOptions
+	1,  // 23: api.api_version:extendee -> google.protobuf.MethodOptions
+	1,  // 24: api.tag:extendee -> google.protobuf.MethodOptions
+	1,  // 25: api.name:extendee -> google.protobuf.MethodOptions
+	1,  // 26: api.api_level:extendee -> google.protobuf.MethodOptions
+	1,  // 27: api.serializer:extendee -> google.protobuf.MethodOptions
+	1,  // 28: api.param:extendee -> google.protobuf.MethodOptions
+	1,  // 29: api.baseurl:extendee -> google.protobuf.MethodOptions
+	1,  // 30: api.handler_path:extendee -> google.protobuf.MethodOptions
+	1,  // 31: api.handler_path_compatible:extendee -> google.protobuf.MethodOptions
+	2,  // 32: api.http_code:extendee -> google.protobuf.EnumValueOptions
+	3,  // 33: api.base_domain:extendee -> google.protobuf.ServiceOptions
+	3,  // 34: api.base_domain_compatible:extendee -> google.protobuf.ServiceOptions
+	35, // [35:35] is the sub-list for method output_type
+	35, // [35:35] is the sub-list for method input_type
+	35, // [35:35] is the sub-list for extension type_name
+	0,  // [0:35] is the sub-list for extension extendee
 	0,  // [0:0] is the sub-list for field type_name
 }
 
@@ -513,7 +599,7 @@ func file_api_proto_init() {
 			RawDescriptor: file_api_proto_rawDesc,
 			NumEnums:      0,
 			NumMessages:   0,
-			NumExtensions: 30,
+			NumExtensions: 35,
 			NumServices:   0,
 		},
 		GoTypes:           file_api_proto_goTypes,
diff --git a/cmd/hz/protobuf/api/api.proto b/cmd/hz/protobuf/api/api.proto
index 5a5cd08..e128ffe 100644
--- a/cmd/hz/protobuf/api/api.proto
+++ b/cmd/hz/protobuf/api/api.proto
@@ -15,9 +15,15 @@ extend google.protobuf.FieldOptions {
   optional string path = 50106;
   optional string vd = 50107;
   optional string form = 50108;
-  optional string go_tag = 51001;
   optional string js_conv = 50109;
   optional string file_name = 50110;
+
+  // 50131~50160 used to extend field option by hz
+  optional string form_compatible = 50131;
+  optional string js_conv_compatible = 50132;
+  optional string file_name_compatible = 50133;
+
+  optional string go_tag = 51001;
 }
 
 extend google.protobuf.MethodOptions {
@@ -38,12 +44,20 @@ extend google.protobuf.MethodOptions {
   optional string param = 50307; // Whether client requests take public parameters
   optional string baseurl = 50308; // Baseurl used in ttnet routing
   optional string handler_path = 50309; // handler_path specifies the path to generate the method
+
+  // 50331~50360 used to extend method option by hz
+  optional string handler_path_compatible = 50331; // handler_path specifies the path to generate the method
 }
 
 extend google.protobuf.EnumValueOptions {
   optional int32 http_code = 50401;
+
+  // 50431~50460 used to extend enum option by hz
 }
 
 extend google.protobuf.ServiceOptions {
   optional string base_domain = 50402;
+
+  // 50731~50760 used to extend service option by hz
+  optional string base_domain_compatible = 50731;
 }
\ No newline at end of file
diff --git a/cmd/hz/protobuf/ast.go b/cmd/hz/protobuf/ast.go
index 0e2803e..c86d21c 100644
--- a/cmd/hz/protobuf/ast.go
+++ b/cmd/hz/protobuf/ast.go
@@ -31,6 +31,7 @@ import (
 	"google.golang.org/protobuf/compiler/protogen"
 	"google.golang.org/protobuf/proto"
 	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/runtime/protoimpl"
 	"google.golang.org/protobuf/types/descriptorpb"
 )
 
@@ -117,7 +118,7 @@ func astToService(ast *descriptorpb.FileDescriptorProto, resolver *Resolver, cmd
 		}
 
 		service.BaseDomain = ""
-		domainAnno := checkFirstOption(api.E_BaseDomain, s.GetOptions())
+		domainAnno := getCompatibleAnnotation(s.GetOptions(), api.E_BaseDomain, api.E_BaseDomainCompatible)
 		if cmdType == meta.CmdClient {
 			val, ok := domainAnno.(string)
 			if ok && len(val) != 0 {
@@ -136,7 +137,7 @@ func astToService(ast *descriptorpb.FileDescriptorProto, resolver *Resolver, cmd
 			path := vpath.(string)
 
 			var handlerOutDir string
-			genPath := checkFirstOption(api.E_HandlerPath, m.GetOptions())
+			genPath := getCompatibleAnnotation(m.GetOptions(), api.E_HandlerPath, api.E_HandlerPathCompatible)
 			handlerOutDir, ok := genPath.(string)
 			if !ok || len(handlerOutDir) == 0 {
 				handlerOutDir = ""
@@ -234,6 +235,16 @@ func astToService(ast *descriptorpb.FileDescriptorProto, resolver *Resolver, cmd
 	return out, nil
 }
 
+func getCompatibleAnnotation(options proto.Message, anno *protoimpl.ExtensionInfo, compatibleAnno *protoimpl.ExtensionInfo) interface{} {
+	if proto.HasExtension(options, anno) {
+		return checkFirstOption(anno, options)
+	} else if proto.HasExtension(options, compatibleAnno) {
+		return checkFirstOption(compatibleAnno, options)
+	}
+
+	return nil
+}
+
 func parseAnnotationToClient(clientMethod *generator.ClientMethod, gen *protogen.Plugin, ast *descriptorpb.FileDescriptorProto, m *descriptorpb.MethodDescriptorProto) error {
 	file, exist := gen.FilesByPath[ast.GetName()]
 	if !exist {
@@ -284,9 +295,8 @@ func parseAnnotationToClient(clientMethod *generator.ClientMethod, gen *protogen
 			}
 		}
 
-		if proto.HasExtension(f.Desc.Options(), api.E_Form) {
+		if formAnnos := getCompatibleAnnotation(f.Desc.Options(), api.E_Form, api.E_FormCompatible); formAnnos != nil {
 			hasAnnotation = true
-			formAnnos := proto.GetExtension(f.Desc.Options(), api.E_Form)
 			hasFormAnnotation = true
 			val := formAnnos.(string)
 			if isStringFieldType {
@@ -301,9 +311,8 @@ func parseAnnotationToClient(clientMethod *generator.ClientMethod, gen *protogen
 			hasBodyAnnotation = true
 		}
 
-		if proto.HasExtension(f.Desc.Options(), api.E_FileName) {
+		if fileAnnos := getCompatibleAnnotation(f.Desc.Options(), api.E_FileName, api.E_FileNameCompatible); fileAnnos != nil {
 			hasAnnotation = true
-			fileAnnos := proto.GetExtension(f.Desc.Options(), api.E_FileName)
 			hasFormAnnotation = true
 			val := fileAnnos.(string)
 			clientMethod.FormFileCode += fmt.Sprintf("%q: req.Get%s(),\n", val, f.GoName)
diff --git a/cmd/hz/protobuf/tags.go b/cmd/hz/protobuf/tags.go
index 30ba1b8..0138686 100644
--- a/cmd/hz/protobuf/tags.go
+++ b/cmd/hz/protobuf/tags.go
@@ -84,8 +84,9 @@ var (
 		api.E_Cookie: "cookie",
 		api.E_Body:   "json",
 		// Do not change the relative order of "api.E_Form" and "api.E_Body", so that "api.E_Form" can overwrite the form tag generated by "api.E_Body"
-		api.E_Form:    "form",
-		api.E_RawBody: "raw_body",
+		api.E_Form:           "form",
+		api.E_FormCompatible: "form",
+		api.E_RawBody:        "raw_body",
 	}
 
 	ValidatorTags = map[*protoimpl.ExtensionInfo]string{api.E_Vd: "vd"}
@@ -165,6 +166,8 @@ func jsonTag(f *descriptorpb.FieldDescriptorProto) (ret model.Tag) {
 	ret.Value = checkSnakeName(f.GetJsonName())
 	if v := checkFirstOption(api.E_JsConv, f.GetOptions()); v != nil {
 		ret.Value += ",string"
+	} else if v := checkFirstOption(api.E_JsConvCompatible, f.GetOptions()); v != nil {
+		ret.Value += ",string"
 	}
 	if !unsetOmitempty && f.GetLabel() == descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL {
 		ret.Value += ",omitempty"
@@ -234,6 +237,8 @@ func injectTagsToModel(f *descriptorpb.FieldDescriptorProto, gf *model.Field, ne
 func getJsonValue(f *descriptorpb.FieldDescriptorProto, val string) string {
 	if v := checkFirstOption(api.E_JsConv, f.GetOptions()); v != nil {
 		val += ",string"
+	} else if v := checkFirstOption(api.E_JsConvCompatible, f.GetOptions()); v != nil {
+		val += ",string"
 	}
 	if !unsetOmitempty && f.GetLabel() == descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL {
 		val += ",omitempty"
@@ -285,11 +290,13 @@ func defaultBindingStructTags(f protoreflect.FieldDescriptor) []model.Tag {
 		api.E_Path,
 		api.E_Query,
 		api.E_Form,
+		api.E_FormCompatible,
 		api.E_Header,
 		api.E_Cookie,
 		api.E_Body,
 		api.E_RawBody,
 	}
+	// If the user provides an annotation, return json tag directly
 	for _, tag := range bindingTags {
 		if vv := checkFirstOption(tag, opts); vv != nil {
 			out[0] = reflectJsonTag(f)
@@ -314,8 +321,13 @@ func defaultBindingStructTags(f protoreflect.FieldDescriptor) []model.Tag {
 		val := checkStructRequire(f, v.(string))
 		out[2] = tag(BindingTags[api.E_Form], val)
 	} else {
-		val := checkStructRequire(f, checkSnakeName(string(f.Name())))
-		out[2] = tag(BindingTags[api.E_Form], val)
+		if v := checkFirstOption(api.E_FormCompatible, opts); v != nil { // compatible form_compatible
+			val := checkStructRequire(f, v.(string))
+			out[2] = tag(BindingTags[api.E_Form], val)
+		} else {
+			val := checkStructRequire(f, checkSnakeName(string(f.Name())))
+			out[2] = tag(BindingTags[api.E_Form], val)
+		}
 	}
 	return out
 }
@@ -382,6 +394,8 @@ func injectTagsToStructTags(f protoreflect.FieldDescriptor, out *structTags, nee
 func getStructJsonValue(f protoreflect.FieldDescriptor, val string) string {
 	if v := checkFirstOption(api.E_JsConv, f.Options()); v != nil {
 		val += ",string"
+	} else if v := checkFirstOption(api.E_JsConvCompatible, f.Options()); v != nil {
+		val += ",string"
 	}
 
 	if descriptorpb.FieldDescriptorProto_Label(f.Cardinality()) == descriptorpb.FieldDescriptorProto_LABEL_REQUIRED {


Test patch:
diff --git a/cmd/hz/testdata/protobuf2/api.proto b/cmd/hz/testdata/protobuf2/api.proto
index 15330da..97ff976 100644
--- a/cmd/hz/testdata/protobuf2/api.proto
+++ b/cmd/hz/testdata/protobuf2/api.proto
@@ -15,9 +15,15 @@ extend google.protobuf.FieldOptions {
   optional string path = 50106;
   optional string vd = 50107;
   optional string form = 50108;
-  optional string go_tag = 51001;
   optional string js_conv = 50109;
   optional string file_name = 50110;
+
+  // 50131~50160 used to extend field option by hz
+  optional string form_compatible = 50131;
+  optional string js_conv_compatible = 50132;
+  optional string file_name_compatible = 50133;
+
+  optional string go_tag = 51001;
 }
 
 extend google.protobuf.MethodOptions {
@@ -29,29 +35,29 @@ extend google.protobuf.MethodOptions {
   optional string options = 50206;
   optional string head = 50207;
   optional string any = 50208;
-  optional string re_get = 50211;
-  optional string re_post = 50212;
-  optional string re_put = 50213;
-  optional string re_delete = 50214;
-  optional string re_patch = 50215;
-  optional string re_options = 50216;
-  optional string re_head = 50217;
-  optional string re_any = 50218;
-  optional string gen_path = 50301;
-  optional string api_version = 50302;
-  optional string tag = 50303;
-  optional string name = 50304;
-  optional string api_level = 50305;
-  optional string serializer = 50306;
-  optional string param = 50307;
-  optional string baseurl = 50308;
-  optional string handler_path = 50309;
+  optional string gen_path = 50301; // The path specified by the user when the client code is generated, with a higher priority than api_version
+  optional string api_version = 50302; // Specify the value of the :version variable in path when the client code is generated
+  optional string tag = 50303; // rpc tag, can be multiple, separated by commas
+  optional string name = 50304; // Name of rpc
+  optional string api_level = 50305; // Interface Level
+  optional string serializer = 50306; // Serialization method
+  optional string param = 50307; // Whether client requests take public parameters
+  optional string baseurl = 50308; // Baseurl used in ttnet routing
+  optional string handler_path = 50309; // handler_path specifies the path to generate the method
+
+  // 50331~50360 used to extend method option by hz
+  optional string handler_path_compatible = 50331; // handler_path specifies the path to generate the method
 }
 
 extend google.protobuf.EnumValueOptions {
   optional int32 http_code = 50401;
+
+  // 50431~50460 used to extend enum option by hz
 }
 
 extend google.protobuf.ServiceOptions {
   optional string base_domain = 50402;
+
+  // 50731~50760 used to extend service option by hz
+  optional string base_domain_compatible = 50731;
 }
\ No newline at end of file
diff --git a/cmd/hz/testdata/protobuf2/psm/psm.proto b/cmd/hz/testdata/protobuf2/psm/psm.proto
index 0561d60..0bf370e 100644
--- a/cmd/hz/testdata/protobuf2/psm/psm.proto
+++ b/cmd/hz/testdata/protobuf2/psm/psm.proto
@@ -9,8 +9,8 @@ import "base.proto";
 import "other/other.proto";
 
 enum EnumType {
-    TWEET = 0;
-    RETWEET = 1;
+  TWEET = 0;
+  RETWEET = 1;
 }
 message UnusedMessageType {
   optional string IsUnusedMessageType = 1;
@@ -74,7 +74,7 @@ message MultiTypeReq {
     // nested oneof
     oneof NestedMsgOneof {
       string IsNestedMsgOneofString = 4;
-      EnumType IsNestedMsgOneofEnumType =5;
+      EnumType IsNestedMsgOneofEnumType = 5;
     }
   }
   // nested message
@@ -92,14 +92,20 @@ message MultiTypeReq {
 }
 
 message MultiTagReq {
-  optional string QueryTag = 1 [(api.query)="query"];
-  optional string RawBodyTag = 2 [(api.raw_body)="raw_body"];
-  optional string CookieTag = 3 [(api.cookie)="cookie"];
-  optional string BodyTag = 4 [(api.body)="body"];
-  optional string PathTag = 5 [(api.path)="path"];
-  optional string VdTag = 6 [(api.vd)="$!='?'"];
-  optional string FormTag = 7 [(api.form)="form"];
-  optional string DefaultTag = 8 [(api.go_tag)="FFF:\"fff\" json:\"json\""];
+  optional string QueryTag = 1 [(api.query) = "query"];
+  optional string RawBodyTag = 2 [(api.raw_body) = "raw_body"];
+  optional string CookieTag = 3 [(api.cookie) = "cookie"];
+  optional string BodyTag = 4 [(api.body) = "body"];
+  optional string PathTag = 5 [(api.path) = "path"];
+  optional string VdTag = 6 [(api.vd) = "$!='?'"];
+  optional string FormTag = 7 [(api.form) = "form"];
+  optional string DefaultTag = 8 [(api.go_tag) = "FFF:\"fff\" json:\"json\""];
+}
+
+message CompatibleAnnoReq {
+  optional string FormCompatibleTag = 1 [(api.form_compatible) = "form"];
+  optional string FilenameCompatibleTag = 2 [(api.file_name_compatible) = "file_name"];
+  optional string JsConvCompatibleTag = 4 [(api.js_conv_compatible) = "true"];
 }
 
 message Resp {
@@ -120,29 +126,29 @@ message MultiNameStyleMessage {
 
 service Hertz {
   rpc Method1(MultiTypeReq) returns(Resp) {
-    option (api.get)="/company/department/group/user:id/name";
+    option (api.get) = "/company/department/group/user:id/name";
   }
   rpc Method2(MultiTypeReq) returns(Resp) {
-    option (api.post)="/company/department/group/user:id/sex";
+    option (api.post) = "/company/department/group/user:id/sex";
   }
   rpc Method3(MultiTypeReq) returns(Resp) {
-    option (api.put)="/company/department/group/user:id/number";
+    option (api.put) = "/company/department/group/user:id/number";
   }
   rpc Method4(MultiTypeReq) returns(Resp) {
-    option (api.delete)="/company/department/group/user:id/age";
+    option (api.delete) = "/company/department/group/user:id/age";
   }
 
 
   rpc Method5(MultiTagReq) returns(Resp) {
-    option (api.options)="/school/class/student/name";
+    option (api.options) = "/school/class/student/name";
   }
   rpc Method6(MultiTagReq) returns(Resp) {
-    option (api.head)="/school/class/student/number";
+    option (api.head) = "/school/class/student/number";
   }
   rpc Method7(MultiTagReq) returns(Resp) {
-    option (api.patch)="/school/class/student/sex";
+    option (api.patch) = "/school/class/student/sex";
   }
   rpc Method8(MultiTagReq) returns(Resp) {
-    option (api.any)="/school/class/student/grade/*subjects";
+    option (api.any) = "/school/class/student/grade/*subjects";
   }
 }
\ No newline at end of file
diff --git a/cmd/hz/testdata/protobuf3/api.proto b/cmd/hz/testdata/protobuf3/api.proto
index 15330da..125c031 100644
--- a/cmd/hz/testdata/protobuf3/api.proto
+++ b/cmd/hz/testdata/protobuf3/api.proto
@@ -15,9 +15,14 @@ extend google.protobuf.FieldOptions {
   optional string path = 50106;
   optional string vd = 50107;
   optional string form = 50108;
-  optional string go_tag = 51001;
   optional string js_conv = 50109;
   optional string file_name = 50110;
+
+  // 50131~50160 used to extend field option by hz
+  optional string go_tag = 51001;
+  optional string form_compatible = 50131;
+  optional string js_conv_compatible = 50132;
+  optional string file_name_compatible = 50133;
 }
 
 extend google.protobuf.MethodOptions {
@@ -29,29 +34,29 @@ extend google.protobuf.MethodOptions {
   optional string options = 50206;
   optional string head = 50207;
   optional string any = 50208;
-  optional string re_get = 50211;
-  optional string re_post = 50212;
-  optional string re_put = 50213;
-  optional string re_delete = 50214;
-  optional string re_patch = 50215;
-  optional string re_options = 50216;
-  optional string re_head = 50217;
-  optional string re_any = 50218;
-  optional string gen_path = 50301;
-  optional string api_version = 50302;
-  optional string tag = 50303;
-  optional string name = 50304;
-  optional string api_level = 50305;
-  optional string serializer = 50306;
-  optional string param = 50307;
-  optional string baseurl = 50308;
-  optional string handler_path = 50309;
+  optional string gen_path = 50301; // The path specified by the user when the client code is generated, with a higher priority than api_version
+  optional string api_version = 50302; // Specify the value of the :version variable in path when the client code is generated
+  optional string tag = 50303; // rpc tag, can be multiple, separated by commas
+  optional string name = 50304; // Name of rpc
+  optional string api_level = 50305; // Interface Level
+  optional string serializer = 50306; // Serialization method
+  optional string param = 50307; // Whether client requests take public parameters
+  optional string baseurl = 50308; // Baseurl used in ttnet routing
+  optional string handler_path = 50309; // handler_path specifies the path to generate the method
+
+  // 50331~50360 used to extend method option by hz
+  optional string handler_path_compatible = 50331; // handler_path specifies the path to generate the method
 }
 
 extend google.protobuf.EnumValueOptions {
   optional int32 http_code = 50401;
+
+  // 50431~50460 used to extend enum option by hz
 }
 
 extend google.protobuf.ServiceOptions {
   optional string base_domain = 50402;
+
+  // 50731~50760 used to extend service option by hz
+  optional string base_domain_compatible = 50731;
 }
\ No newline at end of file
diff --git a/cmd/hz/testdata/protobuf3/psm/psm.proto b/cmd/hz/testdata/protobuf3/psm/psm.proto
index 972a85c..7b19022 100644
--- a/cmd/hz/testdata/protobuf3/psm/psm.proto
+++ b/cmd/hz/testdata/protobuf3/psm/psm.proto
@@ -92,6 +92,12 @@ message MultiTagReq {
   }
 }
 
+message CompatibleAnnoReq {
+  optional string FormCompatibleTag = 1 [(api.form_compatible) = "form"];
+  optional string FilenameCompatibleTag = 2 [(api.file_name_compatible) = "file_name"];
+  optional string JsConvCompatibleTag = 4 [(api.js_conv_compatible) = "true"];
+}
+
 message Resp {
   optional string Resp = 1;
 }