Protobuf Language Guide(proto3)-1

A Simple Example

Let’s begin with a simple example, if you want to define a search request with three paraments: a query string, the particular page of results and a number of results per page. Then we can write the .proto file like this:

syntax = "proto3";

maeeage SearchResult {
	string query = 1;
	int32 page_number = 2;
	int32 result_per_page = 3;
}

We need to notice that the first line of the file specifies that you’re using proto3 syntax: if you don’t do this the protocol buffer compiler will assume you are using proto2.

From the example above, we can see that each field in the message definition has a unique number.These field numbers are used to identify your fields in the message binary format, and should not be changed once your message type is in use. In my last blog, you can note that a number – 15. So, why is 15? Cause field numbers in the range 1 through 15 take one byte to encode, including the field number and the field’s type. But field number in the range of 16 through 2047 take two bytes.

So you should reserve the numbers 1 through 15 for very frequently occurring message elements. Remember to leave some room for frequently occurring elements that might be added in the future.

Some Rules

The first one is about the Message field, and Message fields can be one of the following:

  • singular: a well-formed message can have zero or one of this field (but not more than one). And this is the default field rule for proto3 syntax.
  • repeated: this field can be repeated any number of times (including zero) in a well-formed message. The order of the repeated values will be preserved.

In proto3, repeated fields of scalar numeric types use packed encoding by default.

Adding More Message Type

We can define many Message Type in a single .proto file:

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

message SearchResponse {
 ...
}

Reserved Fileds

One way to make sure the field which has been removed can be reuse in the future is to specify that the field numbers, also, you can specify that your reserved numeric value range goes up to the maximum possible value using the max keyword.

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

Note that you can’t mix field names and field numbers in the same reserved statement.

Scalar Value Types

You can got a table to show the type specified in the .proto file, and the corresponding type in the automatically generated class. And the basic type-specific has the defaults number:

  • For strings, the default value is the empty string.
  • For bytes, the default value is empty bytes.
  • For bools, the default value is false.
  • For numeric types, the default value is zero.
  • For enums, the default value is the first defined enum value, which must be 0.
  • For message fields, the field is not set. Its exact value is language-dependent. See the generated code guide for details.

Enumerations

When you’re defining a message type, you might want one of its fields to only have one of a pre-defined list of values.

For example:

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;
}

As you can see, the Corpus enum’s first constant maps to zero: every enum definition must contain a constant that maps to zero as its first element. This is because:

  • There must be a zero value, so that we can use 0 as a numeric default value.
  • The zero value needs to be the first element, for compatibility with the proto2 semantics where the first enum value is always the default.

You can define aliases by assigning the same value to different enum constants. To do this you need to set the allow_alias option to true, otherwise the protocol compiler will generate an error message when aliases are found.

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.
}

Reference: https://developers.google.cn/protocol-buffers/docs/proto3

发布了16 篇原创文章 · 获赞 0 · 访问量 1314

猜你喜欢

转载自blog.csdn.net/weixin_41036574/article/details/95941532