This is a creation in Article, where the information may have evolved or changed.
PROTOBUF syntax
GRPC recommends using Proto3, this section only describes the common syntax, more advanced use posture please refer to the Official document
Message definition
A message type definition describes a request or the corresponding message format, which can contain several types of fields. For example, define a message format for a search request that contains query strings, page numbers, and the number of pages per page.
syntax = "proto3";message SearchRequest { string query = 1; // 查询字符串 int32 page_number = 2; // 页码 int32 result_per_page = 3; // 每页条数}
The first line declares that the Protobuf version used is Proto3
SearchRequest defines three fields, each with a semicolon ending with a double slash to //
add a comment.
field type declaration
All fields require a predecessor declaration data type, the above example specifies two numeric types and a string type. There are compound types in addition to the basic scalar types, such as enumerations, other message types, and so on.
Identifiers tags
As you can see, in the definition of a message, each field has a unique numeric type identifier . These identifiers are used to identify the binary format of a field in a message, and the type in use should not be arbitrarily altered. Note that the identity within [1-15] occupies only one byte at the time of encoding, including identifiers and field types. The identifier between [16-2047] occupies 2 bytes. It is recommended that you use identifiers between [1-15] for frequently occurring message elements. If you consider possible or extended frequent elements later, you can reserve some identifiers.
The minimum identifier can start at 1, maximum to 229-1, or 536,870,911. identifiers between [19000-19999] cannot be used, and these identifiers are reserved in the PROTOBUF protocol implementation. These reserved identifiers are used in the. proto file and are compiled with an error.
Field rules
Repeated: The identity field can be repeated any time, like an array
Proto3 does not support required and optional in Proto2
Add more message types
A. proto file can define multiple message types, which are typically used to define multiple related messages at the same time, such as defining both a search request and a response message in the same. Proto file:
syntax = "proto3";// SearchRequest 搜索请求message SearchRequest { string query = 1; // 查询字符串 int32 page_number = 2; // 页码 int32 result_per_page = 3; // 每页条数}// SearchResponse 搜索响应message SearchResponse { ...}
Add Comment
Add comments to the. proto file, support C-style double slash //
line comments
Reserved fields and identifiers
You can use the reserved keyword to specify reserved fields and reserved identifiers:
message Foo { reserved 2, 15, 9 to 11; reserved "foo", "bar";}
Note that you cannot mix field names and identifiers in a reserved declaration.
. proto File Compilation results
When you run a file using the protocol buffer compiler, the .proto
compiler generates code for the selected language, using the .proto
message type defined in the file, the service interface contract, and so on. Different languages generate different code formats:
C + +: Each .proto
file generates a file .h
and a .cc
file, each message type corresponds to a class
Java: Generates a .java
file with one class for each message, and a special Builder
class to create the message interface
Python: Posture is not the same, the .proto
message type in each file generates a module with a static descriptor, and a meta-class Metaclass to create the required Python data access class at run time
Go: Generate a .pb.go
file, each message type corresponds to a struct body
Ruby: A .rb
Ruby module that generates a file that contains all the message types
Javanano: Java-like, but does not contain Builder
classes
OBJECTIVE-C: Each .proto
file generates one pbobjc.h
and one pbobjc.m
file
C #: Generate .cs
file contains, one class for each message type
Please refer to the official API documentation for more information on how to use various languages.
Data type
A description of the official documentation is directly quoted here:
. Proto |
C + + |
Java |
Python |
Go |
Ruby |
C # |
Double |
Double |
Double |
Float |
Float64 |
Float |
Double |
Float |
Float |
Float |
Float |
Float32 |
Float |
Float |
Int32 |
Int32 |
Int |
Int |
Int32 |
Fixnum or Bignum |
Int |
Int64 |
Int64 |
Long |
ING/LONG[3] |
Int64 |
Bignum |
Long |
UInt32 |
UInt32 |
INT[1] |
INT/LONG[3] |
UInt32 |
Fixnum or Bignum |
UInt |
UInt64 |
UInt64 |
LONG[1] |
INT/LONG[3] |
UInt64 |
Bignum |
ULong |
Sint32 |
Int32 |
Int |
Intj |
Int32 |
Fixnum or Bignum |
Int |
Sint64 |
Int64 |
Long |
INT/LONG[3] |
Int64 |
Bignum |
Long |
Fixed32 |
UInt32 |
INT[1] |
Int |
UInt32 |
Fixnum or Bignum |
UInt |
Fixed64 |
UInt64 |
LONG[1] |
INT/LONG[3] |
UInt64 |
Bignum |
ULong |
Sfixed32 |
Int32 |
Int |
Int |
Int32 |
Fixnum or Bignum |
Int |
Sfixed64 |
Int64 |
Long |
INT/LONG[3] |
Int64 |
Bignum |
Long |
bool |
bool |
Boolean |
Boolean |
bool |
Trueclass/falseclass |
bool |
String |
String |
String |
STR/UNICODE[4] |
String |
String (UTF-8) |
String |
bytes |
String |
ByteString |
Str |
[]byte |
String (Ascii-8bit) |
ByteString |
Refer to Protocol Buffer Encoding for encoding rules for these types at serialization.
[1] Java
[2] all
[3] 64
[4] Python
Default value
String type defaults to an empty string
BYTE type default is NULL byte
Boolean type Default False
Value type defaults to 0 values
The enums type defaults to the first defined enumeration value, which must be 0
Specific behavior for default values for different languages refer to generated code guide
Enum (enum) TODO
Use a different message
message SearchResponse { repeated Result results = 1;}message Result { string url = 1; string title = 2; repeated string snippets = 3;}
The message supports nested use as a field type in another message
Importing definition (Import)
You can import a type that is declared in a different profile by using an import statement
import "others.proto";
Protocol the buffer compiler looks for the -I / --proto_path
imported file in the directory specified by the parameter, and if it is not specified, it is found by default in the current directory.
Message nesting
message SearchResponse { message Result { string url = 1; string title = 2; repeated string snippets = 3; } repeated Result results = 1;}
Internally declared message type names can be used only internally, and external references require a pre-parent message name, such as Parent.Type
:
message SomeOtherMessage { SearchResponse.Result result = 1;}
Multilayer Nesting Support:
message Outer { // Level 0 message MiddleAA { // Level 1 message Inner { // Level 2 int64 ival = 1; bool booly = 2; } } message MiddleBB { // Level 1 message Inner { // Level 2 int32 ival = 1; bool booly = 2; } }}
Message Update TODO
Map type
Proto3 supports map type declarations:
map<key_type, value_type> map_field = N;message Project {...}map<string, Project> projects = 1;
The key, value type can be a built-in scalar type, or it can be a custom message type
field does not support repeated
attributes
Do not rely on the map type's field order
Package (Packages)
.proto
use the package
declaration package name in the file to avoid naming conflicts.
syntax = "proto3";package foo.bar;message Open {...}
In other message format definitions, the type can be used in the same way as the package name + message name , such as:
message Foo { ... foo.bar.Open open = 1; ...}
In different languages, the package name definition has different effects on the code that is generated after compilation:
C + +: corresponds to a C + + namespace, for example in Open
a namespace foo::bar
In Java: The package is used as the Java bundle name unless an option is specified option jave_package
Python: The package is ignored
Go: The package name is used by default unless an option is specified option go_package
In Javanano: with Java
In C #: The package is converted to a camel-like namespace, for example Foo.Bar
, unless an option is specified option csharp_namespace
Defining Services (Service)
If you want to use the message type in an RPC (remote method call) system, you can .proto
define an RPC service interface in the file, and the protocol buffer compiler will generate the service interface code based on the different languages you choose. For example, if you want to define an RPC service and have a method that receives SearchRequest
and returns one SearchResponse
, you can .proto
define it in a file like this:
service SearchService { rpc Search (SearchRequest) returns (SearchResponse) {}}
The generated interface code acts as a contract between the client and the server, and the server must implement all of the interface methods defined, and the client directly invokes a method of the same name to initiate a request to the server. Compared to the egg, it is necessary to specify a request message even if the parameter is not required on the business, an empty message is generally defined.
Option (Options)
You can annotate a range of options when you define a. proto file. The options do not change the meaning of the entire file statement, but can affect how it is handled in a particular environment. Full options are available for viewing google/protobuf/descriptor.proto
.
Some options are file-level, meaning that it can be used for the top-level scope and is not contained within any message, enum, or service definition. Some options are message-level and can be used inside the message definition. Of course, some options can be used in fields, enum types, enum values, service types, and service methods. But so far, there is no valid option to work with these types.
Here are some of the most common options:
java_package
(File Option): Specifies the package in which the Java class is generated, and if there is no explicit declaration java_package in the. proto file, the default package name is used. No need to generate Java code when not working
java_outer_classname
(File Option): Specifies the name of the generated Java class, and if Java_outer_classname is not explicitly declared in the. proto file, the generated class name will be generated according to the name of the. proto file, in the camel-named manner. such as (Foo_bar.proto generated Java class named Foobar.java), do not need to generate Java code does not play any role
objc_class_prefix
(File Option): Specifies the Objective-c class prefix, preceded by all classes and enumerated type names. Without a default value, you should use 3-5 uppercase letters. Note that all 2-letter prefixes are reserved by Apple.
Basic specifications
A description file as a .proto
file suffix, except for statements that are not defined by a struct, ending with a semicolon
Structure definitions include: message, service, enum
RPC method definition end of semicolon optional
The name of the message is named by the hump, and the field name is separated by lowercase letters and dashes.
message SongServerRequest { required string song_name = 1;}
Enums type name using Hump naming method, field naming by uppercase and underline
enum Foo { FIRST_VALUE = 1; SECOND_VALUE = 2;}
Service and RPC method names are used in a camel-named style
Detailed go language compilation results TODO
The message corresponds to the struct in Golang, and after compiling the Go code, the field name is converted to Camel
Compile
.proto
generate Java, Python, C + +, Go, Ruby, Javanano, Objective-c, or C # code from a well-defined file and need to install the compiler protoc
. Refer to the GitHub Project google/protobuf installation compiler. The go language needs to install a special plugin at the same time: Golang/protobuf.
To run the command:
protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR --go_out=DST_DIR --ruby_out=DST_DIR --javanano_out=DST_DIR --objc_out=DST_DIR --csharp_out=DST_DIR path/to/file.proto
Here is only a reference, the specific language of the compilation of examples, please refer to the detailed documentation, where the use of the go language posture in other chapters detailed description:
C + + generated code reference
Java Generated Code reference
Python Generated Code reference
Go Generated Code reference
Objective-c Generated Code reference
C # generated code reference
Spit Groove: According to the official document step operation does not necessarily succeed Oh!
More
Any message type
oneof field
customizing options
These usages are rarely used in practice and are not described here in detail, especially in the advanced usage of Custom option designs, which are required to refer to the official documentation.
Reference
Sample code for this series