a.proto
syntax = "proto2"; //protoc3生成代码兼容proto2语法
package pkgA;
message Example {
}
ba.proto
package pkgB.pkgA;
message Example {
}
b.proto
syntax = "proto3"; //protoc3生成代码兼容proto2语法
package pkgB;
import "test1/a.proto";
import "test1/ba.proto";
message Example {
}
message Test {
Example simple = 9; // ①
// 使用全名来引用 pkgA 中的 example
.pkgA.Example field_in_pkgA = 1; // ②
// 使用包名+类型名来引用
pkgB.Example field_in_pkgB = 2; // ③
pkgA.Example field_in_pkgA2 = 3; // ④
pkgB.pkgA.Example field_in_pkgc = 4; // ⑤
}
类型引用规则说明部分
类型名中的 .
表示全限定名(全名),.pkg.msg
精确地表示 msg
属于 pkg
。如果没有 .
,则需要按照一定的规则查找类型。
- 对于情况①:没有包的情况,以当前文件的包为准,最终结果:
pkgB.Example
。 - 对于情况②:以
.
开头表示全名,最终结果:.pkgA.Example
。 - 对于情况③:包名是
pkgB
,首先从当前包(当前文件与pkgB
拼接),即.pkgB.pkgB
中查找Example
,即.pkgB.pkgB.Example
。但没有找到,则会全局搜索,即.pkgB.Example
。 - 对于情况④:包名是
pkgA
,首先从当前包即.pkgB.pkgA
中查找Example
,最终结果:.pkgB.pkgA.Example
。假如没找到,则会从全局搜索符号,即搜索.pkgA.Example
。 - 对于情况⑤:首先从当前包查找,由于没找到,从全局符号中搜索,最终结果:
.pkgB.pkgA.Example
。
总结部分
- 对于全名,直接查找对应的
pkg
。详细步骤是,搜索当前文件的所有import
,排除pkg
不匹配的import
文件,然后依次搜索哪个文件中有对应的类型。 - 对于没有类型
pkg
的情况,只从当前文件所在的包中搜索类型。 - 其他情况,依次执行
- a. 在类型
pkg
前面拼接上当前文件的pkg
,在所有包名为文件pkg.类型pkg
一致的import
文件中,搜索该类型。 - b. 在所有包名与当前文件一致的
import
文件中,搜索该类型。
- a. 在类型