Golang gRPC practice grammar serial three Protobuf

Protobuf grammar

gRPC recommended proto3, this section only describes the common syntax, the use of more advanced gestures refer to the official documentation

Message definitions

A message definition describes a request type or corresponding message format may comprise a plurality of field types. E.g. define a search request message format, each request contains a query string, the page number, page number.

syntax = "proto3";

message SearchRequest {
    string query = 1; // 查询字符串 int32 page_number = 2; // 页码 int32 result_per_page = 3; // 每页条数 }

protobuf version of the first line of the Statement of proto3

SearchRequest defines three fields, each field declarations end with a semicolon, the double slash can be used //to add comments.

Field type declaration

All the fields need to pre-declared data type, two examples of the above specified type, and a numeric string type. In addition to the basic types of scalar type as well as a composite, such as enumeration, other message types.

Identifier Tags

Can be seen, the definition of the message, each field has a unique numeric identifier. These identifiers are used in the binary format identifier field in the message, the type used should not be altered arbitrarily. Note that, the identification [1-15] in the coding only occupies one byte, contains the identifier and field types. Between [16-2047] Identifier 2 bytes. Recommended usage identifier [1-15] is a message between frequently occurring elements. May be extended or frequent after considering the elements, you can set aside some identifier.

Smallest identifier may start from a maximum to 229--1, or 536,870,911. Identifier can not be used between the [19000-19999], Protobuf these protocol identifiers is reserved. Using these reserved identification number .proto file then compile-time error.

Field Rules

  • repeated: identification field may be repeated any number of times, similar to the array

  • proto3 does not support the required and optional proto2

Add more message types

.Proto a file can define multiple message types, typically for simultaneously defining a plurality of related messages, for example, while defining a search request and response messages in the same file .proto:

syntax = "proto3";

// SearchRequest 搜索请求
message SearchRequest { string query = 1; // 查询字符串 int32 page_number = 2; // 页码 int32 result_per_page = 3; // 每页条数 } // SearchResponse 搜索响应 message SearchResponse { ... }

add notes

.Proto add comments to files, supports C-style double slash //single-line comments

Reserved field identifier

You can use reserved keywords specified reserved field and reserved identifiers:

message Foo {
    reserved 2, 15, 9 to 11;
    reserved "foo", "bar"; }

Note that you can not mix field names and identifiers in a reserved statement.

.proto file compiled results

When a protocol buffer compiler run .prototime files, the compiler generates code for the selected language, for use in .protoa message type definition file, service interface conventions and the like. Different generated code format different languages:

  • C ++: each .protofile to generate a .hfile and a .ccfile type of each message corresponding to a class

  • Java: generating a .javafile, each message corresponding to a same class, as well as a special Builderclass for creating a message interface

  • Python: posture not the same for each .protofile type to generate a static message descriptor block containing the module with a metaclass metaclass create Python classes need to access data at runtime

  • Go: generating a .pb.gofile, each message type corresponds to a structure

  • Ruby: generating a .rbfile Ruby module comprising all message types

  • JavaNano: similar to Java, but does not include the Builderclass

  • Objective-C: each .protofile to generate a pbobjc.hand a pbobjc.mdocument

  • C #: generating a .csfile contains, for each message type corresponds to a class

More use of various languages refer to the official API documentation

type of data

Here direct reference to the official document described:

.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 Bignan long
uint32 uint32 int[1] int/long[3] uint32 Fixnum or Bignum uint
uint64 uint64 long[1] int/long[3] uint64 Bignan ulong
sint32 int32 int intj int32 Fixnum or Bignum int
sint64 int64 long int/long[3] int64 Bignan long
fixed32 uint32 int[1] int uint32 Fixnum or Bignum uint
fixed64 uint64 long[1] int/long[3] uint64 Bignan ulong
sfixed32 int32 int int int32 Fixnum or Bignum int
sfixed64 int64 long int/long[3] int64 Bignan 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

These types of encoding rules about when serialized refer to the  Protocol Buffer Encoding .

[1] java

[2] all

[3] 64

[4] Python

Defaults

  • String type defaults to an empty string

  • Default is null bytes byte type

  • Boolean Default false

  • The default value is 0 Value Type

  • enums type defaults to the first enumeration value defined, must be 0

Reference to specific acts of defaults in different languages  generated code guide

Enumeration (Enum) TODO

Other Message

message SearchResponse {
    repeated Result results = 1; } message Result { string url = 1; string title = 2; repeated string snippets = 3; }

message supports nested, as in another message type field

Import definition (Import)

You can use other types of import statement to import the description file declarations

import "others.proto";

protocol buffer compiler will  -I / --proto_pathfind the imported file in the directory specified, if the parameter is not specified, the default looks in the current directory.

Nested Message

message SearchResponse {
    message Result { string url = 1; string title = 2; repeated string snippets = 3; } repeated Result results = 1; }

Message type names declared inside can only be used directly in internal references need to pre-parent message name on the outside, such as Parent.Type:

message SomeOtherMessage {
    SearchResponse.Result result = 1;
}

Support nested:

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 Types

proto3 support map type declaration:

map<key_type, value_type> map_field = N;

message Project {...}
map<string, Project> projects = 1; 
  • Button, built-in value types may be scalar type, or may be a custom message type

  • Field does not support repeatedproperty

  • Do not rely map type field order

Package (Packages)

In .protousing the document packagedeclared package name, to avoid naming conflicts.

syntax = "proto3";
package foo.bar;
message Open {...}

Other message formats can be used in the definition of the package and name message name mode to type of use, such as:

message Foo {
    ...
    foo.bar.Open open = 1;
    ...
}

In different languages, different effects package names generated after the definition of the compiled code:

  • In C ++: namespace corresponding to C ++, for example, Openbe in the namespace foo::barof

  • In Java: package will be implemented as a Java package name unless you specify option jave_packageoptions

  • In Python: package is ignored

  • Go in: default package name as the package name unless you specify option go_packageoptions

  • JavaNano in: with Java

  • In C #: package will be converted to camel namespace, such as Foo.Bar, unless specified option csharp_namespaceoptions

Define Service (Service)

If you want the message type is used RPC (Remote Method Invocation) system, you may .protodefine an RPC service interface file, protocol buffer compiler generates the service interface code depending on the selected language. For example, to define an RPC service and having a method that receives SearchRequestand returns a SearchResponse, in this case can be .protodefined as follows file:

service SearchService {
    rpc Search (SearchRequest) returns (SearchResponse) {} }

All interface methods generate interface code as the agreement of the client and the server, the server must implement defined, the client calls the same method on initiating direct request to the server. Comparison of egg pain is not required even if the business must also specify a parameter request message, typically define an empty message.

Options (Options)

When you define .proto file can mark a series of options. Options file does not change the meaning of the entire statement, but under certain circumstances can affect the processing mode. You can view the complete list of available options google/protobuf/descriptor.proto.

Some of the options is the file level, meaning that it can act on the top-level scope is not included in any messages inside, enum or service definition. Some options are message-level, it can be used in the definition of inside information. Of course, some options can act in the field, enum type, enum values, type of service and service methods. But so far, no action can be an effective option in these types.

What are some common options:

  • java_package (File option): Specifies the package to generate java classes where, if there is no clear statement java_package in .proto file, will use the default package name. When the code does not work does not need to generate java

  • java_outer_classname (File option): Specifies the name of the Java class generation, if not explicitly stated in java_outer_classname .proto file, the generated class name will be used camel naming .proto be generated based on the name of the file. The (foo_bar.proto generated java class named FooBar.java), has no effect when the need to generate java code

  • objc_class_prefix (File option): Specifies the Objective-C class prefix, will be before all classes and pre-enumeration type name. There is no default value, you should use 3-5 capital letters. Note that all two-letter prefix is ​​reserved for Apple.

Basic specification

Description files .protoas file suffix, statements except structure defined by a semicolon

  • Structure definition includes: message, service, enum

  • The method defined semicolon at the end of optional rpc

Message named using the naming hump, field names in lower case letters underlined spaced manner

message SongServerRequest {
    required string song_name = 1; }

Enums type names using camel named, field name in uppercase and underlined separate ways

enum Foo {
    FIRST_VALUE = 1;
    SECOND_VALUE = 2; }

Service and uniform application of the method name rpc named Camel

Detailed results of the Go language compiler TODO

golang message corresponding to the struct, the compiler generates code that go, is converted to a field name Camel

Compile

Defined by .protogenerating Java, Python, C ++, Go , Ruby, JavaNano, Objective-C, or C # code file, you need to install the compiler protoc. Reference Github project google / protobuf installation .Go language compiler will need to install a special plug-: golang / protobuf .

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

Only reference here is like, the compiler examples of specific language, please refer to the detailed documentation, which, Go language use posture will explain in detail in other sections:

Tucao: shining the official document step by step is not guaranteed Oh!

More

  • Any message type

  • Oneof field

  • Custom Options

These usages are rarely used in practice, not described in detail here, especially custom design options for advanced usage, the need to refer to the official documentation .

reference

This series of sample code

Read the 20k Updated on 2017-01-19
 
 

2 reviews
Jancd : 

当需要定义一个消息类型的时候,可能想为一个字段指定某“预定义值序列”中的一个值。例如,假设要为每一个SearchRequest消息添加一个 corpus字段,而corpus的值可能是UNIVERSAL,WEB,IMAGES,LOCAL,NEWS,PRODUCTS或VIDEO中的一个。 其实可以很容易地实现这一点:通过向消息定义中添加一个枚举(enum)就可以了。一个enum类型的字段只能用指定的常量集中的一个值作为其值(如果尝 试指定不同的值,解析器就会把它当作一个未知的字段来对待)。在下面的例子中,在消息格式中添加了一个叫做Corpus的枚举类型——它含有所有可能的值 ——以及一个类型为Corpus的字段:

message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
enum Corpus {

UNIVERSAL = 0;
WEB = 1; IMAGES = 2; LOCAL = 3; NEWS = 4; PRODUCTS = 5; VIDEO = 6;

}
Corpus corpus = 4;
}
如果给枚举常量定义别名, 需要设置allow_alias option 为 true, 否则 protocol编译器会产生错误信息。

enum EnumAllowingAlias {
option allow_alias = true;
UNKNOWN = 0;
STARTED = 1;
RUNNING = 1;
}
enum EnumNotAllowingAlias {
UNKNOWN = 0;
STARTED = 1;
// RUNNING = 1; // Uncommenting this line will cause a compile error inside Google and a warning message outside.
}
枚举常量必须在32位整型值的范围内。因为enum值是使用可变编码方式的,对负数不够高效,因此不推荐在enum中使用负数。如上例所示,可以在 一个消息定义的内部或外部定义枚举——这些枚举可以在.proto文件中的任何消息定义里重用。当然也可以在一个消息中声明一个枚举类型,而在另一个不同 的消息中使用它——采用MessageType.EnumType的语法格式。

当对一个使用了枚举的.proto文件运行protocol buffer编译器的时候,生成的代码中将有一个对应的enum(对Java或C++来说),或者一个特殊的EnumDescriptor类(对 Python来说),它被用来在运行时生成的类中创建一系列的整型值符号常量(symbolic constants)。

Guess you like

Origin www.cnblogs.com/ExMan/p/12163113.html