protobuf 自定义extend
1、proto2 extension
proto2 extensions 官网指导说明:
https://developers.google.com/protocol-buffers/docs/proto#extensions
定义:
https://github.com/golang/protobuf/blob/4846b58453b3708320bdb524f25cc5a1d9cda4d4/internal/testprotos/proto2_proto/test.proto#L266
使用方法:
https://github.com/golang/protobuf/blob/master/proto/extensions_test.go
本文重点说明proto3,但proto3也是在proto2的基础上展开的,在理解以上链接内容可以继续向下阅读。
2、proto3 option
proto3 不支持extension,只支持option, option传值设置:
https://developers.google.com/protocol-buffers/docs/proto3#options
具体option可以分为:
FileOptions
MessageOptions
FieldOptions
OneofOptions
EnumOptions
EnumValueOptions
ServiceOptions
MethodOptions
UninterpretedOption
其字段定义见:
https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/descriptor.proto
官网也有对应使用测试:
https://github.com/protocolbuffers/protobuf/blob/master/csharp/protos/unittest_custom_options_proto3.proto
3、go代码 处理proto3 option值
test.proto:
syntax = "proto3";import "google/protobuf/descriptor.proto";
import "google/protobuf/any.proto";extend google.protobuf.FileOptions {uint64 file_opt1 = 1000;
}
message mymessage{int32 x = 10;
}
extend google.protobuf.MessageOptions {mymessage mymsg = 1000 ;
}
extend google.protobuf.FieldOptions {string field_opt1 = 1000;string field_opt2 = 1001;mymessage field_opt3 = 1002;
}
extend google.protobuf.OneofOptions {int32 oneof_opt1 = 1000;
}
extend google.protobuf.EnumOptions {int32 enum_opt1 = 1000;
}
extend google.protobuf.EnumValueOptions {int32 enum_value_opt1 = 1000;
}
extend google.protobuf.ServiceOptions {sint64 service_opt1 = 1000;
}option (file_opt1) = 1;message usemymessage{option(mymsg) = {x:1} ;string field1 = 1 [(field_opt1)="field1", (field_opt2)="field1"];string field2 = 2 [(field_opt3) = {x: 100;}];oneof AnOneof{option (oneof_opt1) = 100;int32 oneofint = 3;string oneofstring = 4;}enum AnEnum {option (enum_opt1) = 100;ANENUM_UNSPECIFIED = 0;ANENUM_VAL1 = 1;ANENUM_VAL2 = 2 [(enum_value_opt1) = 100];}int32 test = 20;repeated google.protobuf.Any details = 21;
}
message usemymessagenonoption{string field1 = 1;string field2 = 2;oneof AnOneof{int32 oneofint = 3;string oneofstring = 4;}enum AnEnum {ANENUM_UNSPECIFIED = 0;ANENUM_VAL1 = 1;ANENUM_VAL2 = 2;}int32 test = 20;repeated google.protobuf.Any details = 21;
}
为了方便测试,下载了https://github.com/golang/protobuf,到proto文件家下新建test文件
把test.proto放入test文件夹内,编译命令 protoc --go_out=. *.proto 生成test.pb.go文件
编译中发现:
- FieldOptions字段不可省略括号
string field1 = 1 [(field_opt1)="field1", (field_opt2)="field1"]; //field_opt1必须加括号
- proto3不能显示设置option default 值
extend google.protobuf.FileOptions {
uint64 file_opt1 = 1000 [default = 100];
}
这样编译时会报Explicit default values are not allowed in proto3错,[default = 100]要删除
然后到proto/extensions_test.go 文件中加入以下测试代码:
func TestProtoOption(t *testing.T) {usm := &test.Usemymessage{Field1: "usm",Field2: "usm",}usmnonopt := &test.Usemymessagenonoption{Field1: "usm",Field2: "usm",}usmf, usmd := descriptor.ForMessage(usm)_, usmnonoptd := descriptor.ForMessage(usmnonopt)//FileOptionsif v, err := proto.GetExtension(usmf.Options, test.E_FileOpt1); err == nil {t.Logf("GetExtensions(usmf.Options, test.E_FileOpt1) file_opt1:%d", *(v.(*uint64)))} else {t.Fatalf("GetExtensions(usmf.Options, test.E_FileOpt1) failed: %v", err)}/*output:GetExtensions(usmf.Options, test.E_FileOpt1) file_opt1:1*///MessageOptionsif _, err := proto.GetExtension(usmnonoptd.Options, test.E_Mymsg); err == nil {t.Fatalf("GetExtension(usmd.Options, test.E_Mymsg) succ")} else {if err := proto.SetExtension(usmnonoptd.Options, test.E_Mymsg, &test.Mymessage{X: 100}); err != nil {t.Logf("Usemymessagenonoption can't SetExtension and GetExtension")}}if v, err := proto.GetExtension(usmd.Options, test.E_Mymsg); err == nil {t.Logf("GetExtension(usmd.Options, test.E_Mymsg) mymsg default:%v", *(v.(*test.Mymessage)))setmymsg := &test.Mymessage{X: 100}if err := proto.SetExtension(usmd.Options, test.E_Mymsg, setmymsg); err == nil {if v1, err1 := proto.GetExtension(usmd.Options, test.E_Mymsg); err1 == nil {t.Logf("GetExtension(usmd.Options, test.E_Mymsg) mymsg after SetExtension:%v", *(v1.(*test.Mymessage)))}}} else {t.Fatalf("GetExtension(usmd.Options, test.E_Mymsg) failed: %v", err)}/*output:Usemymessagenonoption can't SetExtension and GetExtensionGetExtension(usmd.Options, test.E_Mymsg) mymsg default:{1 {} [] 0}GetExtension(usmd.Options, test.E_Mymsg) mymsg after SetExtension:{100 {} [] 0}*///FieldOptionsfor _, field := range usmd.Field {if *(field.Name) == "field1" {if v, err := proto.GetExtensions(field.Options, []*proto.ExtensionDesc{test.E_FieldOpt1, test.E_FieldOpt2}); err == nil {t.Logf("field1 field_opt1 default:%v, field1 field_opt1 default:%v", *(v[0].(*string)), *(v[1].(*string)))} else {t.Fatalf("GetExtension(usmd.Options, []*proto.ExtensionDesc{test.E_FieldOpt1, test.E_FieldOpt2}) failed: %v", err)}}if *(field.Name) == "field2" {if v, err := proto.GetExtension(field.Options, test.E_FieldOpt3); err == nil {t.Logf("field2 field_opt3 default:%v", *(v.(*test.Mymessage)))} else {t.Fatalf("GetExtensions(field.Options, test.E_FieldOpt3) failed: %v", err)}}}/*output:field1 field_opt1 default:field1, field1 field_opt1 default:field1field2 field_opt3 default:{100 {} [] 0}*/}
protobuf 自定义extend相关推荐
- js 自定义extend函数
转自:http://blog.csdn.net/openblogs/article/details/25169165 1.实现: /*** 有一个函数为extend,该函数有两个参数* arg1* a ...
- 给力开源,.Net开源地址大收集
一.基础类库: 1,项目名:Npoi 资源星级:★★★ (个人评的) 介绍:NPOI - 一个能帮助你直接读写office文件流的库 系统教程:http://www.cnblogs.com/tonyq ...
- github代码_GitHub启动代码空间
github代码 Codespaces works like a virtual Integrated Development Environment (IDE) on the cloud. 代码空间 ...
- Reactor And Gev 详解 通俗易懂
reactor 详解 在类似网关这种海量连接, 很高的并发的场景, 比如有 10W+ 连接, go 开始变得吃力. 因为频繁的 goroutine 调度和 gc 导致程序性能很差. 这个时候我们可以考 ...
- 开源相关社区/项目一览
开源项目托管: http://www.apache.org/ http://www.googlecode.com/ http://www.sf.net/ http://www.github.com/ ...
- [转]Google Protocol Buffers 之.Net应用
吴剑 2011-2-22 wu-jian.cnblogs.com 前言 最近接到一个跨平台的测试项目,服务端Linux,是Java开发的一系列Socket接口,客户端Windows,所以准备用.Net ...
- Google Protocol Buffers 之.Net应用
Google Protocol Buffers 之.Net应用 吴剑 2011-2-22 原创文章,转载必需注明出处:http://www.cnblogs.com/wu-jian/ 前言 最近接到一个 ...
- C++微服务RPC框架,一文带你彻底搞懂 RPC
RPC(Remote Procedure Call),是一个大家既熟悉又陌生的词,只要涉及到通信,必然需要某种网络协议.我们很可能用过HTTP,那么RPC又和HTTP有什么区别呢?RPC还有什么特点, ...
- PHP简易实现批量生成html静态页面
PHP简易实现批量生成html静态页面 大家好,我骇Yangrl. 原来哈起一坨(蠢萌),写了页面以后,复制十份,挨着改里面的文本,imp,url等内容,做成十张页面(类似新闻详情页啊,商品详情页等) ...
最新文章
- linux配置文件语法错误,linux vim配置文件(语法高亮)
- 系统设计面试题思路综述
- mysql表 c#实体类,创建基于MySQL表中的C#类
- linux df命令无反馈,Linux-df命令
- 常量表达式(constexpr)
- AtCoder Grand Contest 018 A
- 企业发文的红头文件_【红头文件写作格式】 公司红头文件格式范本
- 京东万能转链API接口 含商品信息优惠券转链 京东线报如何转链?
- jQuery篮球计分器
- 第三方接口开发(短信验证码)
- 巧用JMP公式,让新变量的生成更简单
- Unity 崩溃问题解决方法——之一
- Linux编程基础案例:第4章Shell编程
- HTML+CSS3(六)——行内元素和块级元素
- python操作服务器(二)
- 手机电容触摸屏技术简介
- SAP ABAP ME23N标准采购订单打印输出配置开发
- Java 实现连接sql server 2000(JDBC数据库访问例子)
- fuchsia Zircon Hypervisor:调测手段
- 0.pytorch lightning 入门
热门文章
- mybatis plus忽略实体类中某一个字段的映射
- 广播和多播,IGMP协议
- vue实现后台实时编辑预览页面,小程序端展示
- Wince6.0 下Camera(OV3640) 驱动开发全程记录
- 中小企业信息化——ERP/CRM
- 智慧旅游的优势和特点有哪些?
- 【微信小程序支付功能】uniapp实现微信小程序支付功能
- 2020年9家互联网大厂职级和薪酬曝光!含阿里腾讯字节美团……
- 01_11_Java语言入门||02_面向对象与常用类||day11_final、权限、内部类、成员变量类型和方法的参数及返回值特例
- 【高等数学】五、微分方程