Files
rikako-note/protobuf/protobuf.md
2025-02-25 12:41:11 +08:00

3.2 KiB
Raw Blame History

protobuf

language guideproto3

定义message type

如下为一个定义search request message format的示例

synatx="proto3"

message SearchRequest {
    string query = 1;
    int32 page_number = 2;
    int32 results_per_page = 3;
}

上述示例含义如下:

  • synatx = "proto3":
    • 代表当前protobuf的language版本为proto3
    • 如果没有指定syntax那么protocol buffer compiler默认会假设在使用proto2
  • Search Request消息定义了3个fields每个field都代表希望包含在message中的一部分数据

Assign Field Numbers

可以为message中的每个field定义一个整数范围为[1,536,870,911],并有如下约束

  • message中所有field的给定数字必须唯一
  • field number [19,000, 19,999]是为Protocol Buffer实现保留的如果使用这些数字protocol buffer compiler将会报错

一旦消息类型被使用后field number就不能被改变field number代表message wire format中的field。

如果对field的field number进行了修改代表删除旧的field并且新建一个相同类型的field。

filed number不应该被重用。

对于频繁被设置的fields应该将其的field number设置为[1,15]。在wire format中field number的值越小占用空间越小。

例如,[1,15]在编码时只占用1字节[16, 2047]则会占用2字节。

重复使用filed number的后果

如果重复使用field number将会造成解码wire-format message的二义性。

对于protobuf wire format其在编码和解码过程中fields的定义必须一致。

field number被限制为29bit故而field number的最大值为536870911

指定字段基数

在protobuf协议中field可以为如下的集中类型

Singular

在proto3中有两种singular field

  • optional(推荐使用): 一个optional field可能有如下两种状态
    • 如果optional field值被设置那么其将会被序列化到wire
    • 如果optional field值未被设置那么该field将会返回一个默认值并且其不会被序列化到wire中
  • implict(不推荐使用):一个隐式字段没有显式基数标签,并且行为如下:
    • 如果field为一个message type那么其行为和optional相同
    • 如果field不是message那么其有两种状态
      • 如果field被设置为非默认值non-zero其会被序列化到wire中
      • 如果field被设置为zero value那么其不会被序列化到wire中

相比于implict,更推荐使用optional,使用optional能更好与proto2相兼容

repeated

代表该field可以在消息中出现0次或多次消息出现的顺序也将被维护

map

代表field为成对的键值对