This is the 20th day of my participation in the August Text Challenge.More challenges in August

Introduction to the

In the last article we had a basic understanding of Google’s Protobuf and were able to generate the appropriate code using the appropriate tools. However, the format of.proto files and the specific types supported are not clear. Today, this article will take you to find out.

Note that the protocol described in this article is proto3.

Define a message

A protobuf body is called a message and can be thought of as a class that we define in our program. We can define this message object in a.proto file and add attributes to it as follows:

syntax = "proto3";

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

The first line of the example above specifies the protocol type of the.proto file. Proto3 is used here, which is the latest version of the protocol. If not specified, proto2 is used by default.

The type definition

Here we define three properties of type String and int32 for the SearchRequest object.

String and int32 are both simple types. Protobuf supports the following simple types:

Protobuf type instructions The corresponding Java type
double A double-precision floating point type double
float Floating point types float
int32 Integer numbers, preferably not negative numbers int
int64 Integer numbers, preferably not negative numbers long
uint32 Unsigned integer int
uint64 Unsigned integer long
sint32 Signed integer int
sint64 Signed integer long
fixed32 A four-byte integer int
fixed64 An 8-byte integer long
sfixed32 A signed integer of 4 bytes int
sfixed64 An 8-byte signed integer long
bool Boolean type boolean
string string String
bytes byte ByteString

Protobuf also supports complex composite and enumerated types.

Enum types are represented as enum types in protobuf. Let’s look at the definition of an enum type:

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;
}
Copy the code

We define an enumeration type Corpus above. Enumeration values defined in enumeration types start from 0, which is also the default value of enumeration types.

In enumerations, you can also define enumerations with the same value, but this requires the allow_alias=true option, as shown below:

message MyMessage1 {
  enum EnumAllowingAlias {
    option allow_alias = true;
    UNKNOWN = 0;
    STARTED = 1;
    RUNNING = 1;
  }
}
message MyMessage2 {
  enum EnumNotAllowingAlias {
    UNKNOWN = 0;
    STARTED = 1;
    // RUNNING = 1;  // Uncommenting this line will cause a compile error inside Google and a warning message outside.
  }
}
Copy the code

In an enumerated type, if we follow-up to delete certain enumerated types, then deleted value may be used by subsequent users, this will cause potential code hidden trouble, in order to solve this problem, the enumeration provides a reserved keyword, enumerated types by the keyword statement, will not be used, as shown below:

enum Foo {
  reserved 2, 15, 9 to 11, 40 to max;
  reserved "FOO", "BAR";
}
Copy the code

The reserved keyword can also be used in the field of message to indicate that these fields should not be used in the future, as follows:

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

The value of the field

As you can see, each field of message is assigned a value that is unique within message and is used to locate the field within the binary message format. So once you’ve defined it, don’t change it.

Note that values 1-15 are represented by 1 byte in binary and values 16-2047 by 2 bytes, so 1-15 is usually used for the most common fields and for fields that may be duplicated to save space after encoding.

The lowest value is 1, the highest value is 2 to the 29th power -1, or 536,870,911. This middle number from 19000 to 19999 is reserved and cannot be used.

When the message is compiled, each field will be converted to the corresponding type, and each field type will be given a different initial value.

The default value for strings is empty string, bytes is empty bytes, bools is false, numeric is 0, and enumeration is the first element of the enumeration.

Field descriptor

Each field of a message can have two descriptors, the first is called singular, which means that there can be zero or one of these fields in a message, which is the default definition in Proto3.

The second, called repeated, means that the field can be repeated in a message, meaning that it represents a collection.

Add comments

Comments in proto are similar in style to C++, and can be used: // or /*… */ style comments, as shown below:

/* This is a comment. */ message SearchRequest {string query = 1; int32 page_number = 2; // page number int32 result_per_page = 3; // Results per page}Copy the code

Nested types

You can also embed a message within a message, as follows:

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

In the above example, we define a Result type in SearchResponse, which in Java can actually be thought of as a nested class.

If you want to use this internal message outside of the message definition class, you can define it with _Parent_._Type_ :

message SomeOtherMessage {
  SearchResponse.Result result = 1;
}
Copy the code

Nested types can be nested arbitrarily, as follows:

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; }}}Copy the code

Map

If you want to define a map in proto, you can write:

map<key_type, value_type> map_field = N;
Copy the code

Here value_type can be of any type except map. Note that maps cannot be repeated.

The order of data in a map is variable, so we cannot rely on the order in which the map is stored to determine the order in which the map is retrieved.

conclusion

These are the things you should pay attention to when using protobuf.

This article is available at www.flydean.com/02-protocol…

The most popular interpretation, the most profound dry goods, the most concise tutorial, many tips you didn’t know waiting for you to discover!

Welcome to pay attention to my public number: “procedures those things”, understand technology, more understand you!