protobufs的全球唯一选项字段编号

时间:2017-06-12 12:24:50

标签: protocol-buffers

在protobuf文档(https://developers.google.com/protocol-buffers/docs/proto#customoptions)中,它说明了自定义选项:

  

最后一件事:由于自定义选项是扩展名,因此必须是   分配的字段编号与任何其他字段或扩展名一样在里面   上面的例子中,我们使用了50000-99999范围内的字段编号。   此范围保留供个人内部使用   组织,所以你可以自由使用这个范围内的数字   内部应用程序。如果您打算在公共场合使用自定义选项   但是,确保这一点非常重要   您的字段编号是全球唯一的。获得全球独一无二的   字段编号,请发送请求   protobuf-global-extension-registry@google.com。只需提供您的   项目名称(例如Object-C插件)和您的项目网站(如果   可用)。通常您只需要一个分机号码。

为什么选项字段编号必须是全局唯一的公共应用程序?碰撞会以什么方式成为问题?

1 个答案:

答案 0 :(得分:1)

基本上,因为你不知道你得到的数据是否正确。

protobuf二进制有线格式存储字段编号和有效负载(对于复杂类型,只是字段编号和子有效负载本身)。没有名称数据。因此:当您存储和检索扩展字段时,您所说的只是"获取字段{字段编号},将其解释为{type}"。如果两个不同的系统使用相同的字段编号扩展相同的数据,那么您无法知道您是否正在获取的数据实际上是那种格式

通常这不是一个问题 - 因为在同样的数据上很少像这样发生冲突;但自定义选项是不同的!我是图书馆作家;我可能希望通过扩展(例如)MessageOptions来添加我的架构解析工具识别的自定义选项。 MessageOptionsDescriptorProto的扩展点,也就是说:option (foo) = "bar";内的message是什么。

为此,我需要为foo分配一个号码。我随意选择5000MessageOptions定义extensions 1000 to max;,这样就可以了。一切都很好。我的工具有效。

我不知道,另一个库作者已选择执行类似的操作并且使用了5000.一旦编译了架构(通过protoc或类似的),我拥有的只是数字。如果我要求来自字段5000的数据,我不知道我是否获得了我的扩展,或者另一个。意思丢失了。好的,推送我还可以查看dependency上的FileDescriptorProto列表,但是......那个命中和未命中。

我不知道字段1中值5000的存在是否为:

option (.mystuff.someext) = 1;

VS

option (.anotherlib.whatever) = -1; // stored as sint32

VS

option (.yetanother.library.option) = true;

如果这些扩展程序的编号均为5000,则它们会在电线上显示相同