- syntax = "proto3";
文件的第一行指定了你使用的是proto3的語法:如果你不指定,protocol buffer 編譯器就會認為你使用的是proto2的語法。這個語句必須出現在.proto文件的非空非注釋的第一行。 - message SearchRequest {......}
message 定義實體 - 基本數據類型
- 注釋符號: 雙斜線,如://xxxxxxxxxxxxxxxxxxx
- 字段唯一數字標識(用於在二進制格式中識別各個字段,上線后不宜再變動):Tags
1到15使用一個字節來編碼,包括標識數字和字段類型(你可以在Protocol Buffer 編碼中查看更多詳細);16到2047占用兩個字節。因此定義proto文件時應該保留1到15,用作出現最頻繁的消息類型的標識。記得為將來會繼續增加並可能頻繁出現的元素留一點兒標識區間,也就是說,不要一下子把1—15全部用完,為將來留一點兒。
標識數字的合法范圍:最小是1,最大是 229 - 1,或者536,870,911。
另外,不能使用19000 到 19999之間的數字(FieldDescriptor::kFirstReservedNumber through FieldDescriptor::kLastReservedNumber),因為它們被Protocol Buffers保留使用 - 字段修飾符:
required:值不可為空
optional:可選字段
singular:符合語法規則的消息包含零個或者一個這樣的字段(最多一個)
repeated:一個字段在合法的消息中可以重復出現一定次數(包括零次)。重復出現的值的次序將被保留。在proto3中,重復出現的值類型字段默認采用壓縮編碼。你可以在這里找到更多關於壓縮編碼的東西: Protocol Buffer Encoding。
默認值: optional PhoneType type = 2 [default = HOME]; - 代理類生成
- C++, 每一個.proto 文件可以生成一個 .h 文件和一個 .cc 文件
- Java, 每一個.proto文件可以生成一個 .java 文件
- Python, 每一個.proto文件生成一個模塊,其中為每一個消息類型生成一個靜態的描述器,在運行時,和一個metaclass一起使用來創建必要的Python數據訪問類
- Go, 每一個.proto生成一個 .pb.go 文件
- Ruby, 每一個.proto生成一個 .rb 文件
- Objective-C, 每一個.proto 文件可以生成一個 pbobjc.h 和一個pbobjc.m 文件
- C#, 每一個.proto文件可以生成一個.cs文件.
- 字段默認值
- strings, 默認值是空字符串(empty string)
- bytes, 默認值是空bytes(empty bytes)
- bools, 默認值是false
- numeric, 默認值是0
- enums, 默認值是第一個枚舉值(value必須為0)
- message fields, the field is not set. Its exact value is langauge-dependent. See the generated code guide for details.
- repeated fields,默認值為empty,通常是一個空list
- 枚舉
第一個元素的value必須為0; - Maps字段類型:map<key_type, value_type> map_field = N;
- map字段不能是
repeated
. - Wire format ordering and map iteration ordering of map values is undefined, so you cannot rely on your map items being in a particular order.
- When generating text format for a
.proto
, maps are sorted by key. Numeric keys are sorted numerically. - When parsing from the wire or when merging, if there are duplicate map keys the last key seen is used. When parsing a map from text format, parsing will fail if there are duplicate keys.
- map字段不能是
- 更新.proto文件
當原有的.proto結構不能滿足業務需求時,可以修改.proto文件,重新生成代理類,修改時需遵循以下原則:- 不能修改已存在字段的唯一數字標識符(tags)
- If you add new fields, any messages serialized by code using your "old" message format can still be parsed by your new generated code. You should keep in mind the default values for these elements so that new code can properly interact with messages generated by old code. Similarly, messages created by your new code can be parsed by your old code: old binaries simply ignore the new field when parsing. Note that unknown fields are discarded when the message is deserialized, so if the message is passed on to new code, the new fields will not still be available (this is different behaviour to proto2, where unknown fields are serialized along with the message).
- 對廢棄的字段,它的tags不能被再次使用,可以不刪除,而是給字段添加“OBSOLETE_ ”前綴,這樣可以避免將來重新使用這個tags
- int32, uint32, int64, uint64, 和bool是完全兼容的,這些字段類型之間可以直接修改
- sint32 和 sint64 是兼容的,但是和其他的數字類型不兼容
- string 和 bytes 是兼容的,由於bytes也是 UTF-8格式
- Embedded messages are compatible with bytes if the bytes contain an encoded version of the message.
- fixed32 和 sfixed32兼容, fixed64和sfixed64兼容
- enum 和 int32, uint32, int64, and uint64 in terms of wire format (note that values will be truncated if they don't fit). However be aware that client code may treat them differently when the message is deserialized: for example, unrecognized proto3 enum types will be preserved in the message, but how this is represented when the message is deserialized is language-dependent. Int fields always just preserve their value.
- Packages支持
- 定義Services
- 其他Options:
- java_package(file option):option java_package = "com.example.foo";
- java_outer_classname(file option ):option java_outer_classname = "Ponycopter";
- optimize_for(file option ):值為SPEED, CODE_SIZE或LITE_RUNTIME;如:option optimize_for = CODE_SIZE;
-
SPEED
(default): The protocol buffer compiler will generate code for serializing, parsing, and performing other common operations on your message types. This code is extremely highly optimized.CODE_SIZE
: The protocol buffer compiler will generate minimal classes and will rely on shared, reflection-based code to implement serialialization, parsing, and various other operations. The generated code will thus be much smaller than withSPEED
, but operations will be slower. Classes will still implement exactly the same public API as they do inSPEED
mode. This mode is most useful in apps that contain a very large number.proto
files and do not need all of them to be blindingly fast.LITE_RUNTIME
: The protocol buffer compiler will generate classes that depend only on the "lite" runtime library (libprotobuf-lite
instead oflibprotobuf
). The lite runtime is much smaller than the full library (around an order of magnitude smaller) but omits certain features like descriptors and reflection. This is particularly useful for apps running on constrained platforms like mobile phones. The compiler will still generate fast implementations of all methods as it does inSPEED
mode. Generated classes will only implement theMessageLite
interface in each language, which provides only a subset of the methods of the fullMessage
interface.
-
- cc_enable_arenas (file option ): 生成C++代碼時啟用arena allocation.
- objc_class_prefix (file option ): 設置 Objective-C class前綴,which is prepended to all Objective-C generated classes and enums from this .proto. There is no default. You should use prefixes that are between 3-5 uppercase characters as recommended by Apple. Note that all 2 letter prefixes are reserved by Apple.
- deprecated (field option): 如果設置為true,則該字段被置為“deprecated”,在新的代碼中不能被繼續使用,In most languages this has no actual effect. In Java, this becomes a @Deprecated annotation. In the future, other language-specific code generators may generate deprecation annotations on the field's accessors, which will in turn cause a warning to be emitted when compiling code which attempts to use the field. If the field is not used by anyone and you want to prevent new users from using it, consider replacing the field declaration with a reserved statement.
int32 old_field = 6 [deprecated=true];
示例:



