Protobuf Language Guide(proto3)-3

Map

We can define a map value in our .proto file:

map<key_type, value_type> map_field = N;

where the key_type can be integral or string type, but enum is not a vaild key_type.The value_type can be any type except another map.

Well, you can define the map like this:

map<string, Project> projects = 3;

There are also some note:

  • Map field cannot be repeated.
  • You cannot rely on your map items being in a particular order.
  • When generating text format for a .protp, maps are sorted by key. Numeric keys are sorted numerically.
  • When parsing a map from text format, parsing may fail if there are duplicate keys.
  • If you provide a key but no value for a map field, the behavior when the field is serialized is language-dependent. In C++, Java, and Python the default value for the type is serialized, while in other languages (like Go) nothing is serialized.

Backwards compatibility

Any protocol buffers implementation that supports maps must both produce and accept data that can be accepted by the following definition.

message MapFieldEntry {
	key_type key = 1;
	value_type value = 2;
}
repeated MapFieldEntry map_field = N;

Packages

We can add an optional package specifier to a .proto file.

package foo.bar;
message Open {...}

You can then use the package specifier when defining fields of your message type:

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

In Go, the package is used as the Go package name, unless you explicitly provide an option go_package in your .proto file.

Defining Services

If you want to use your message types with an RPC system, you can define an RPC services interface in a .proto file.

service SearchService {
	rpc Search (SearchRequest) return (SearchResponse);
}

The most straightforward RPC system to use with protocol buffers is gRPC: a language- and platform-neutral open source RPC system developed at Google. gRPC works particularly well with protocol buffers and lets you generate the relevant RPC code directly from your .proto files using a special protocol buffer compiler plugin.

Proto3 supports a canonical encoding in JSON, making it easier to share data between systems. The encoding is described on a type-by-type basis in the table below.

proto3 JSON JSON example Notes
message object {“fooBar”:v, “g”:null, …} Message field names are mapped to lowerCamelCase and become JSON object keys.null is an accepted value for all field types and treated as the default value of the corresponding field type.
enum string “FOO_BAR” The name of the enum value as specified in proto is used. Parsers accept both enum names and integer values.
map<K,V> object {“k”:v, …} All keys are converted to strings.
repeated V array [v, …] null is accepted as the empty list [].
bool true, false true, false
string string “Hello World!”
bytes base64 string "YWJjMTIzIT8kKiYoKSctPUB+" JSON value will be the data encoded as a string using standard base64 encoding with paddings.
int32, fixed32, uint32 number 1, -10, 0 JSON value will be a decimal number. Either numbers or strings are accepted.
int64, fixed64, uint64 string “1”, “-10” JSON value will be a decimal string. Either numbers or strings are accepted.
float, double number 1.1, “NaN”, “Infinity” JSON value will be a number or one of the special string values “NaN”, “Infinity”, and “-Infinity”.
Any object {"@type": “url”, “f”: v, …} If the Any contains a value that has a special JSON mapping, it will be converted as follows: {"@type": xxx, "value": yyy}.Otherwise, the value will be converted into a JSON object, and the "@type" field will be inserted to indicate the actual data type.
Timestamp string "1972-01-01T10:00:20.021Z" Uses RFC 3339, where generated output will always be Z-normalized and uses 0, 3, 6 or 9 fractional digits.
Duration string "1.000340012s", "1s" Generated output always contains 0, 3, 6 or 9 fractional digits, depending on required precision, followed by the suffix “s”.
Struct object { … }
Wrapper types various types 2, “2”, “foo”, true Wrappers use the same representation in JSON as the wrapped primitive type, except that null is allowed and preserved during data conversion and transfer.
FieldMask string “f.fooBar, h”
ListValue array [foo, bar, …]
Value value Any JSON value
NullValue null JSON null
Empty object {} An empty JSON object

JSON options:

  • Emit fields with default values: Fields with default values are omitted by default in proto3 JSON output. An implementation may provide an option to override this behavior and output fields with
    their default values. So we must be careful with default value.
  • Ignore unknown fields: Proto3 JSON parser should reject unknown fields by default but may provide an option to ignore unknown fields in parsing.
  • Use proto field name instead of lowerCamelCase name: By default proto3 JSON printer should convert the field name to lowerCamelCase and use that as the JSON name. An implementation may provide an option to use proto field name as the JSON name instead.
  • Emit enum values as integers instead of strings: The name of an enum value is used by default in JSON output. An option may be provided to use the numeric value of the enum value instead.

Options

There are many options that we always use, but mostly are affect Java, C++ or Obeject-C, so we jump this part. But we can see the full options from the google/protobuf/descriptor.proto.

Generating Your Classes

If you want to use .proto file to generate Go code, you need to run the protocol buffer compile protoc on the .proto.

The Protocol Compiler is invoked as follows:

protoc --proto_path=IMPORT_PATH --go_out=DST_DIR path/to/file.proto
  • IMPORT_PATH specifies a directory in which to look for .proto files when resolving import directives. If omitted, the current directory is used.
  • --go_out generates Go code in DST_DIR. See the Go generated code reference for more.
  • You must provide one or more .proto files as input. Multiple .proto files can be specified at once. Although the files are named relative to the current directory, each file must reside in one of the IMPORT_PATHs so that the compiler can determine its canonical name.
发布了16 篇原创文章 · 获赞 0 · 访问量 1312

猜你喜欢

转载自blog.csdn.net/weixin_41036574/article/details/96438878
今日推荐