protobuf的option使用
一、需求
来源于工作中的一个需求:在传递message时需要对message中不同的字段进行不同的处理,而处理方式通过注释标注在了每个字段的定义后。
类似于有下面这样一个消息:
其中字段1是始终需要的,字段2和3需要在默写条件下才获取。但这是一种one of的结构,因为1 2 3可能同时出现。并且因为time1、time2这些条件是固定的,所以如果可以把他们像从配置文件中一样读出来而不需要传输是最好的,最后找到的解决方案之一就是protobuf的option。
二、protobuf.option
Option是protobuf文件自带的一种属性,通过在.proto文件中标注options来达到在不影响整个文件中消息含义的情况下支持对protobuf在特定环境下的特定处理。
Option 分为三个级别:FileOptions MessageOptions FieldOptions
2.1 FileOptions
文件级属性,作用于一个最外的范围,不包含在任何消息内部、enum或服务定义中。
Protobuf自带一些文件级option,主要是作用于编程语言级的操作,例如:
-
- java_package**
· 这个选项表明生成java类所在的包。如果在.proto文件中没有明确的声明java_package,就采用默认的包名。当然了,默认方式产生的 java包名并不是最好的方式,按照应用名称倒序方式进行排序的。如果不需要产生java代码,则该选项将不起任何作用。如:option java_package = “com.example.foo”;
- java_package**
-
- cc_enable_arenas**
对于C++产生的代码启用arena allocation。
- cc_enable_arenas**
自带的文件级option在decriptor.proto 中;
**2.2 MessageOptions **
消息级option被定义在消息定义的内部,也有些选项可以作用在域、enum、类型及服务中。
2.3 FieldOptions
字段级option只起效于消息中的单个字段。
三、代码使用示例
以上三种option都支持自定义,代码示例如下:
.proto文件中定义自己需要的option, 下图分别定义了文件、消息、字段级的option各一个,其中文件级option是个string,其余两个是个message,并且对文件级option定义后直接赋值
接下来,定义了三个消息,每个消息都定义了自己的消息级option, 然后三个消息分别定义了 0条字段option , 1条字段option , 每个字段都有option ;
最后在CPP中:
定义了一个PBInfo保存每条消息的相关option,以及一个解析的函数和输出函数
然后对三种消息解析并输出:
最终结果: