协议缓冲区导入消息取决于另一个导入的消息

时间:2015-03-04 15:39:37

标签: import protocol-buffers

关于import语句,google说https://developers.google.com/protocol-buffers/docs/proto#services

  

您可以通过导入来使用其他.proto文件中的定义。要导入另一个.proto的定义,可以在文件顶部添加import语句。   默认情况下,您只能使用直接导入的.proto文件中的定义。

......听起来不错,但那是怎么回事:

1.proto:

message M1{
   required string foo = 1;
}

2.proto:

import "1.proto";
message M2{
    required M1 m_1 = 1;
}

3.proto:

import "2.proto";
message M3{
    required M2 m_2 = 1;
}

因此,在解析3.proto时,M1不应该是可访问的,因为1.proto不是从2.proto公开导入的。 但是,M2应该是,因为它直接从3.proto ...

导入

那么M2.m_1怎么样?编译器应该如何生成类?

1 个答案:

答案 0 :(得分:2)

文档的含义是,如果您想在文件中引用M1,则必须导入1.proto,如果要在文件中引用M2,必须导入2.proto。您 not 需要显式导入隐式/传递依赖项。在不导入M2的情况下使用1.proto非常好。

编译器实际上遵循传递导入并读取所有三个文件,以便为3.proto生成代码。此外,在C ++中,3.pb2.h#include "2.pb2.h",而#include "1.pb2.h"依次为M1。该规则只是一种语法规则。

为什么要这个规则?好吧,考虑一下您是否可以在3.proto中直接使用1.proto而不显式导入2.proto,只是因为您导入了自己导入1.proto的{​​{1}}。现在考虑,2.proto的维护者是否决定删除字段m_1。现在2.proto没有使用M1,因此维护者决定删除1.proto的导入。但现在3.proto已被破坏,因为它依赖2.proto导入1.proto的事实!

这是C ++包含的常见问题。我不想在Protobufs中遇到同样的问题,所以我制定了一条规则,你必须明确导入所有文件,声明你在自己的文件中明确使用的类型。