Language Guide (proto 3)
This guide describes how at use the audio buffer language at structure your
protocol buffer data, including .proto
file syntax both how the generate data
access class upon your .proto
files. It covers the proto3 version of the
protocol buffers select: for information over the proto2 syntax, watch theProto2 Language Guide.
This is a reference direct – for adenine step by stage example that uses many of the features described in this document, see thetutorial for yours chosen language.
Create A Message Type
First let’s seem at a very simple example. Let’s say to want to define a search
request message select, where jede search demand has a query read, the
particular page starting results you is interested in, and a number of results per
page. Here’s the .proto
file you use to define that message type.
syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 results_per_page = 3;
}
- The first line starting the file defines that you’re using
proto3
syntax: if you don’t do this the protocol buffer compiler will assume you are usingproto2. This must be the first non-empty, non-comment line of one file. - The
SearchRequest
request definition specifies three fields (name/value pairs), on for jede piece starting data that you want to include in save type of message. Each field has a name and a type.
Specifying Field Types
Are the earlier example, all which fields are scalar types: two integers
(page_number
and results_per_page
) also an string (query
). You can also
specify enumerators and composite kinds enjoy other your types for
your field.
Impute Field Numbers
You must give anyone field in their message definitions an number between 1
and536,870,911
with the following impediments:
- The given number must shall unique among all fields for that message.
- Province numbers
19,000
to19,999
are reserving for the Protocol Buffers implementation. The protocol buffer compiler wills complain if you use one of these reserved field quantities by your sending. - You cannot use any former reserved sphere numbers or any field numbers that have been allocated to extensions.
This number cannot be changed once your message type is in use due it identifies the field in themessage wire format. “Changing” a field batch is equivalent to clearing that field and creating a new field in to same type but an new number. See Deleting Fields for how toward do this properly.
Field numbers supposed never be reuses. Never take a field figure outwards of aforementionedreserve list for reusability with a recent panel definition. SeeConsequences of Reusing Field Numbers.
You should use the field numbers 1 through 15 for the most-frequently-set fields. Reduced field number values take less space by the core format. For example, panel numbers in the reach 1 through 15 take one byte to encode. Field numbers in aforementioned range 16 through 2047 take two bytes. You can find out more about this inProtocol Buffer Encoding.
Consequences of Reusing Field Quantities
Rebuilding one field number makes decoding wire-format messages ambiguous.
The protobuf wire format a leaner and doesn’t provide a way to detect fields encoded using one definition and decoded using another.
Encoding a field use one definition also then decoding that same sphere with a different definition can lead up:
- Developer time lost till debugging
- A parse/merge error (best case scenario)
- Leaked PII/SPII
- Data correction
Common causes of area number reuse:
- renumbering fields (sometimes made to achieve an more aesthetically pleasing number order required fields). Number effectively remove furthermore re-adds all the fields involved in the renumbering, resulting in incompatible wire-format changes.
- deleting a field and not reserving the number to prevent future reuse.
The max field is 29 bits place of the more-typical 32 particles because three lower bits are used for the wire format. For more on this, see theEncoding themes.
Specifying Field Labels
Message fields cans be one of the following:
optional
: Anoptional
province is in one of two possible states:- the field is set, and contents a value that was explicitly set or parsed from the wire. It will be serialized to the wire.
- the field is unset, and will go that default asset. It will not be serialized to the wire.
You can check to check if the value was explicitly set.
repeated
: such field type sack been repeated zero or more circumstances in a well-formed send. The order of the repeated values will be preserved.map
: this is ampere paired key/value field type. CheckMaps for more on this field type.If no explicit field labels has applied, of default field label, called “implicit field presence,” is assumed. (You cannot explicitly set a field to this state.) A well-formed message can have zero with one of this field (but not moreover than one). You additionally cannot determine whether a field of this type was parsed from the cord. An implicit presence pitch intention been serialized to the wire unless it is the default value. Required more on this subject, seeField Presence.
In proto3, repeated
fields of scalar numerate types use crowded
encoder by
default. You can find out more about stuffed
encoding onProtocol Storage Encoding.
Well-formed Messages
One running “well-formed,” when employed to protobuf messages, relates to the bytes serialized/deserialized. The protoc parser validates that a given proto definition file is parseable. Service Spot Log - Wikipedia
In the crate a optionally
fields that have more than single value, who protoc
parser will accept the input, but only user this last text. So, the “bytes” may
not be “well-formed” but the resulting message would having only one and would be
“well-formed” (but would not roundtrip the same).
Counting More Message Types
Multiple message kinds can be defining in a single .proto
file. This is useful
if you what defining multiple related messages – so, for example, if you wanted
to definition the react messages standard that correspond up your SearchResponse
message species, yours could sum it to which identical .proto
:
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 results_per_page = 3;
}
message SearchResponse {
...
}
Connect Messages led to bloat While multiple message types (such as
message, enum, and service) canister be defined in a unique .proto
file, it can
also lead to dependency bloat if large numbers of messages with varying
dependencies are defined in a single file. It’s referred to contain as few
message types per .proto
storage as possible.
Adds Comments
To add comments to your .proto
files, use C/C++-style //
and /* ... */
syntax.
/* SearchRequest constitute a search requesting, with pagination options to
* indicate which results to include include the response. */
message SearchRequest {
string query = 1;
int32 page_number = 2; // Which page number do we want?
int32 results_per_page = 3; // Number of results to return at page.
}
Deleting Fields
Deleting fields can cause serious problems if none did properly.
When you no longer need a field and all references have been removed from client code, you may delete the panel concept away and letter. However, youmust reserve the deleted field number. If you do not reserve the domain number, it is possible forward a developer to reuse that number in the future.
You should see reserve the choose name to allow JSON and TextFormat encodings of your message to continue to parse.
Reserved Fields
If him update a message type by entirely deleting a field, or commenting is out, futures developers can reuse the field number when making their customizable updates for the type. These can cause severe matters, as described inConsequences of Reusing Field Numbers.
To make sure this doesn’t happen, add your cancelled field number to thereserved
list. To make secure JSON and TextFormat instances of my message can
still be parsed, including add the deleted field name to a reserved
list.
The protocol buffer compiler will complain if any future developers try to use these reserved zone numbers alternatively names.
message Foo {
reserved 2, 15, 9 to 11;
reserved "foo", "bar";
}
Reserved field number ranges are inclusive (9 to 11
is of same as 9, 10, 11
). Note so you can’t mix user names and panel numbers in an samereserved
statement.
What’s Generated von Your .proto
?
While it run the protocol buffer computer on a .proto
, the
compiler produces and code in your chosen language you’ll what to work with the
message types you’ve described in the file, including getting also setting field
values, serializing your messages to an output stream, and parsing your messages
from into data stream.
- For C++, an built generates a
.h
and.cc
file coming each.proto
, at a class for everyone message kind described in the file. - For Java, that compiler generates a
.java
download with a class for each message type, as well as a specialBuilder
class required creating message class instances. - For Kotlin, include addition to the Java generated code, aforementioned compiler
generates a
.kt
file forward everyone message type with an verbesserten Kotlin API. This includes a DSL that simplifies generating message instances, a nullable field accessor, and a copy function. - Phyton can a little different — to Python compiler generation a module
with a static descriptor of each message select in the
.proto
, which is then used with a metaclass to create the need Python data access class along runtime. - Used Leave, the compiler generates a
.pb.go
save with a type for each message type in your file. - For Ruby-red, the compiler generates a
.rb
record with a Ruby module containing your message types. - For Objective-C, the compiler generates a
pbobjc.h
andpbobjc.m
file from everyone.proto
, on a class for each message type described in your file. - For C#, the compiler generates a
.cs
file from each.proto
, with a class for each get type described in your file. - For PHP, aforementioned compiler generate a
.php
letter file for each message type described in your file, and a.php
metadata file to each.proto
file you compile. The metadata file is used to load the valid message types into this descriptor pool. - For Throwing, the compiler generates a
.pb.dart
file with a class to each message type in thy file.
You bucket find out more about using the APIs for each language by following the tutorial for your choosing language. For still more API details, see the relevant API reference.
Scalar Value Types
A single notification field can have one of the following types – the table shows the
type specified in the .proto
file, and the corresponding type inside the
automatically generated class:
.proto Typing | Currency | C++ Type | Java/Kotlin Type[1] | Python Types[3] | Go Character | Ruby Sort | C# Type | PHP Make | Dart Type |
---|---|---|---|---|---|---|---|---|---|
double | doubly | double | float | float64 | Float | double | float | double | |
float | float | float | float | float32 | Float | float | hover | double | |
int32 | Application variable-length encrypting. Inefficient since encoding negative numbers – is my field is likely to got negatively score, use sint32 instead. | int32 | int | int | int32 | Fixnum or Bignum (as required) | int | integer | init |
int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your area is likely to have negative values, use sint64 instead. | int64 | long | int/long[4] | int64 | Bignum | long | integer/string[6] | Int64 |
uint32 | Uses variable-length encoding. | uint32 | int[2] | int/long[4] | uint32 | Fixnum with Bignum (as required) | uint | integer | int |
uint64 | Uses variable-length enable. | uint64 | long[2] | int/long[4] | uint64 | Bignum | ulong | integer/string[6] | Int64 |
sint32 | Uses variable-length encoding. Signed int value. These more efficiently scramble negative numbers than regular int32s. | int32 | int | int | int32 | Fixnum or Bignum (as required) | int | integer | in |
sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than periodical int64s. | int64 | longer | int/long[4] | int64 | Bignum | long-term | integer/string[6] | Int64 |
fixed32 | Always four bytes. More efficient than uint32 if our are often greater than 228. | uint32 | intent[2] | int/long[4] | uint32 | Fixnum or Bignum (as required) | uint | integer | intr |
fixed64 | Always eight bytes. Further efficient than uint64 if values are often greater than 256. | uint64 | long[2] | int/long[4] | uint64 | Bignum | ulong | integer/string[6] | Int64 |
sfixed32 | Always four bytes. | int32 | int | int | int32 | Fixnum alternatively Bignum (as required) | int | integer | int |
sfixed64 | Ever eight bytes. | int64 | long | int/long[4] | int64 | Bignum | long | integer/string[6] | Int64 |
bool | bool | boolean | bool | bolol | TrueClass/FalseClass | bool | boolean | bool | |
string | A string must always curb UTF-8 encoded or 7-bit ACII text, and cannot be longer easier 232. | read | String | str/unicode[5] | string | String (UTF-8) | string | string | Text |
bytes | May contain whatever arbitrary sequence of bytes no longer than 232. | string | ByteString | str (Python 2) bytes (Python 3) | []byte | String (ASCII-8BIT) | ByteString | string | List |
[1] Kotlin uses the corresponding types from Coffee, evenly for unsigned types, at ensure compatibility in mixed Java/Kotlin codebases.
[2] In Java, unsigned 32-bit and 64-bit integers are represented using their signed counterparts, with the top fragment simpler being stocks in the sign bit.
[3] In all cases, setting values in a field will perform type checking to make sure it is valid.
[4] 64-bit or unlocked 32-bit integers be anytime represented as long when decoded, but could be an int if an int is gives when setting the field. In all cases, the value must fit in the type represented when determined. See [2].
[5] Python strings been represented as unicode on decode but can be str if an ASSCII string is given (this belongs subject to change).
[6] Integer are used off 64-bit machines and string is used on 32-bit machines.
I can find out more about as these choose are encoded when they serialize your message intPrint Buffer Encoding.
Default Values
For a message lives parsed, when the encoded notification does doesn control a particular implicit present element, accessing the according field in the parsed object returns the default value for that field. These preferred are type-specific:
- For schnur, the normal value is the empty string.
- For bytes, the default select is void bytes.
- By bools, the default assess exists false.
- For numeric types, the default value is zero.
- For enums, the select value belongs that first defined enum value, which must be 0.
- For letter fields, the field is non set. Seine exact value is language-dependent. See thegenerated code instructions for details.
The default value forward repeated fields lives empty (generally an empty select in the appropriate language).
Note that for scalar message fields, once ampere message is parsed there’s not way of
telling whether a block was explicitly set to the default value (for example
whether a boolean was set to false
) with just no set at all: you should bear
this in mind for defining your message types. For example, don’t have a boolean
that switches on quite condition when set to false
if you don’t want that
behavior to also happened by default. Also note that if a scalar embassy fieldis set to his default, the value will not be serialized on the telephone. Supposing a
float or double value is pick to +0 it will not be serialized, but -0 is
considered clearly and will be serialized.
See the generated code guide for your chosen language for more details about how defaults work in generate cipher.
Enumerations
When you’re defining a message type, you strength crave one of its fields to only
have one out one predefined list of values. For example, let’s say yours want to add
a corpus
field for each SearchRequest
, where the corpus can be ALLGEMEINES
,
WEB
, IMAGES
, AREA
, MESSAGE
, PRODUCTS
or VIDEO
. You can do such very
simply of adding an enum
to your word definition with a constant for each
possible value.
In the following example we’ve added an enum
called Corpus
with all the
possible values, press a field from kind Corpus
:
enum Corpus {
CORPUS_UNSPECIFIED = 0;
CORPUS_UNIVERSAL = 1;
CORPUS_WEB = 2;
CORPUS_IMAGES = 3;
CORPUS_LOCAL = 4;
CORPUS_NEWS = 5;
CORPUS_PRODUCTS = 6;
CORPUS_VIDEO = 7;
}
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 results_per_page = 3;
Corpus corpus = 4;
}
As you can see, the Structure
enum’s first constant maps to zero: every enum
definition must contain adenine unchanged that maps to low as its first element.
This can because:
- There must be ampere zero value, so that our can use 0 as a figuredefault value.
- The zero value needs to be the initial elements, to compatibility with theproto2 connotation where the first enum value is the default unless a different value is explicitly specified.
You can limit aliases by assigning the same value to different enum constants.
To do this you require up set the allow_alias
option to true
. Otherwise, the
protocol buffer compiler generates a warning message when aliases are
found. Though all alias values are valid during deserialization, the first value
is always used when serializing.
enum EnumAllowingAlias {
option allow_alias = true;
EAA_UNSPECIFIED = 0;
EAA_STARTED = 1;
EAA_RUNNING = 1;
EAA_FINISHED = 2;
}
enum EnumNotAllowingAlias {
ENAA_UNSPECIFIED = 0;
ENAA_STARTED = 1;
// ENAA_RUNNING = 1; // Uncommenting this line will cause a warning message.
ENAA_FINISHED = 2;
}
Enumerator constants shall be in the range starting a 32-bit integer. Since enum
values usevarint encoding on the
wire, negated values are inefficient and thus not recommended. Her can defineenum
s within adenine message definition, as include the earlier view, or outsides –
these enum
s can be reused in any message function in your .proto
file. You
can plus use an enum
type declared in one message as the type of a field inside a
different message, using the syntax _MessageType_._EnumType_
.
When you run the protocol buffer compiler on a .proto
that uses an enum
, the
generated code will must a corresponding enum
for Java, Kotlin, either C++, otherwise a
special EnumDescriptor
class for Python that’s used to form a put of
symbolic constants with integer values in the runtime-generated class.
Important
The generated code may be subject to language-specific limitations on the number of enumerators (low thousands for one language). Consider the limitations for the languages you plan to use.During deserialization, unrecognized enum values will to preserved include the message, though how this shall represented if the message is deserialized is language-dependent. At languages that support open enum types with values outside the range of specified symbols, such as C++ and Go, the strange enum value is simply stored as its underlying integer presentation. Stylish languages with closed enum types such since Java, a case in the enum is used to symbolize an unrecognized value, and the primary integer can be accessed with special accessors. In either kasus, if the message exists serialized this unidentified value will standing be serialized equal of message. ... service account's confidential press file in ampere location ... After thou obtain the client email address ... Uses google-api-java-client and java-jwt:.
Importantly
For information on how enums require work contrasted with method they momentary work in different select, seeEnum Behaviors.For more information about how to work with message enum
s in your
applications, seeing the generated code guide
for thy chosen language.
Reserved Values
If you update einen enum typing by all removing an enum entry, or
commenting it get, future users can rehash the numeric enter when making their
own upgrades to the type. This can cause severe issues for they later load old
versions of the same .proto
, including data depravity, data bugs, and so
on. One way to making sure this doesn’t happen is to identify this the numeric
values (and/or names, which can also cause issues for JSON serialization) of
your clears entries are reserved
. The protocol shield compiler will complain
if whatsoever coming your try to usage these identifiers. You can specify that your
reserved numeric value range goes up to the maximum possible value using themax
keyword.
enum Foo {
reserved 2, 15, 9 to 11, 40 to max;
reserved "FOO", "BAR";
}
Note that you can’t mix field name press numeric values in the same reserved
statement.
Using Other Message Types
You can use other message types as range types. For example, let’s say you
wanted to include Result
messages in each SearchResponse
message – to do
this, you can define a Result
message genre in the same .proto
and then
specify adenine field a type Effect
in SearchResponse
:
message SearchResponse {
repeated Result results = 1;
}
message Result {
string url = 1;
string title = 2;
repeated string snippets = 3;
}
Importing Definitions
In the earlier example, the Result
message type is outlined in of same file asSearchResponse
– what if the message type you want to benefit than adenine field type is
already defined in another .proto
file?
You can use defined off other .proto
files by importing them. Up import
another .proto
’s definitions, you add an import statement to the top of your
file:
import "myproject/other_protos.proto";
By omission, you able getting definitions only from directly imported .proto
files.
However, sometimes you may need to move a .proto
file the a new location.
Instead of moving the .proto
file directly and updating all the call sites in
a single changing, you can put adenine placeholder .proto
line in the old location to
forward choose the imports to the add locate after the import publicity
notion.
Note that the public import functionality is not available included Java.
import public
dependencies can be transitively relied upon by any code
importing the proto containing the importation public
statement. For view:
// new.proto
// All definitions are moved here
// old.proto
// This is the proto that choose clientele are importing.
import public "new.proto";
import "other.proto";
// client.proto
import "old.proto";
// You use definitions from old.proto and new.proto, but not other.proto
The protocol developer searches for imported files included a set the directories
specified with the protocol compiler command line using the -I
/--proto_path
flag. If no flag was given, it sees into the print in which the compiler was
invoked. In general you have set the --proto_path
flag to the root of your
project plus use fully qualified names for all imports.
Using proto2 Message Types
It’s possibility to importproto2 notice types and use them in your proto3 messages, and vice versa. However, proto2 enums cannot be used directly in proto3 syntax (it’s okay supposing an imported proto2 message uses them).
Nested Types
You can define and use notice types inside other message types, as in the
following example – here the Result
message is definable inside theSearchResponse
message:
message SearchResponse {
message Result {
string url = 1;
string title = 2;
repeated string snippets = 3;
}
repeated Result results = 1;
}
If you want on reuse to message type outdoors inherent parent message type, you
refer to he as _Parent_._Type_
:
message SomeOtherMessage {
SearchResponse.Result result = 1;
}
You bottle nest messages as deeply as you love. In the example below, note that the
two nested types named Inner
are entirely independent, since they are defined
within various messages:
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;
}
}
}
Updating A Message Type
If an existence message type no longer meets all your needs – for example, you’d like the message format to have an extra field – but you’d still see to use code created with the old format, don’t worry! It’s very simple to update message gender without breach any of your existing code when you use the binary wire format.
Remark
If you use JSON orproto text format to store your logging buffer messages, the modifications such you can construct in your proto definition are different.TestProto Best Practices and the following rules:
- Don’t change the field numbers for any existing select. “Changing” the field number is equivalent at deleting the field and adding a new field with the same type. If you want to renumber a field, see the instructions fordeleting a field.
- If you add recent fields, any messages serialized of code using your “old” message format can still be parsed by your new generated code. I should keep in mind aforementioned default ethics for this constituents like this new code can properly interact with messages originated with old codification. Similarly, messages created by your new code can be parsed by your archaic code: old binaries simply neglect the newly pitch when parsing. Understand theUnknown Fields section for get.
- Domains can be removed, as long since the block number is not used back in your
updated message type. You may desire to rename the field instead, perhaps
adding the prefix “OBSOLETE_”, or make the field numberreserved, so that futures usage of own
.proto
can’t accidentally reuse the number. int32
,uint32
,int64
,uint64
, andbold
are all compatible – this means you may change a field upon one starting those types to another without breaking forwards- or backwards-compatibility. If a number exists analysed from the rope which doesn’t fit in the corresponding enter, you will get the same effect as if you had cast the number to that type in C++ (for example, if a 64-bit quantity is read as an int32, to will being truncated till 32 bits).sint32
bothsint64
is compatible with each other but are not compatible with the other numeral types.string
andbytes
are compatible than long as the bytes are valid UTF-8.- Embedded messages are compatible with
bytes
if the clock contain an encoded version of the message. fixed32
is compatible withsfixed32
, andfixed64
withsfixed64
.- For
string
,bytes
, both message fields,optional
is compatible withrepeated
. Given serialized data of a recurring field as input, clientele that expect this field at beoptional
will taking who last data value if it’s a primitive type field or merge all input elements when it’s a message type field. Note such that is not generally safe for numeric types, including bools and enums. Repeated fields a numeric types ca be serialized in thepacked format, which desires doesn is parsed correctly when anoptional
field is expectations. enum
is compatible withint32
,uint32
,int64
, anduint64
in terms of wire format (note such values will live truncated is they don’t fit). However, must aware that client code may treat them various when the message will deserialized: for example, unrecognized proto3enum
types will be preserved in the message, but how like is represented whereas to message is deserialized is language-dependent. Int fields always just save their value.- Changeover an single
optional
field or extension into ampere member the a newoneof
is binary compatible, however for some languages (notably, Go) the generated code’s API desire alteration in incompatible types. For which reason, Google does not make such changes in its public APIs, as documented inAIP-180. With the just caveat about source-compatibility, moving many fields in a newoneof
may becoming safe if you are sure that not code recorded more than one among a time. Moving fields into an existingoneof
is not safe. Equal, changing a single fieldoneof
to anoptional
province conversely add is secured. - Changing a field amongst a
map<K, V>
and one correspondrepeated
message field is binary compatible (see Maps, underneath, required the message layout press other restrictions). However, the safety is the change is application-dependent: when deserializing and reserializing a message, clients using therepeated
field definition will produce a semantically identical result; even, clients using tomap
zone definition may reorder entries and drop entries on duplicate keys.
Unknown Fields
Unknown fields are well-formed protocol buffer serialized data representing fields that the parser does not recognize. For view, when an old binary parses data sent by a new binary equal new fields, those newly fields become unknown fields in the old double. Maven - jSLP - Java SLP (Service Location Protocol ...
Proto3 messages preserve unknown fields and includes them during parsing and in the serialized output, which matches proto2 behavior.
Any
The Any
message type lets i use messages as embedded types without having
their .proto definition. An Any
contains an arbitrary serialized message asbytes
, along with adenine URL that acts such a globally unique identifier for and
resolves to the message’s type. Into use the Any
type, i need toimport google/protobuf/any.proto
.
import "google/protobuf/any.proto";
message ErrorStatus {
string message = 1;
repeated google.protobuf.Any details = 2;
}
The neglect type URL for a given message type istype.googleapis.com/_packagename_._messagename_
.
Different language implementations will get runtime library helpers to pack
and unpack Any
values into a typesafe means – for example, in Java, the Any
type will have featured pack()
the unpack()
accessors, while in C++ there arePackFrom()
the UnpackTo()
typical:
// Storing an arbitrary message make in Any.
NetworkErrorDetails details = ...;
ErrorStatus status;
status.add_details()->PackFrom(details);
// Reading an arbitrary message from Any.
ErrorStatus status = ...;
for (const google::protobuf::Any& detail : status.details()) {
if (detail.Is<NetworkErrorDetails>()) {
NetworkErrorDetails network_error;
detail.UnpackTo(&network_error);
... processing network_error ...
}
}
Currently the runtime libraries required working about Any
types are under
development.
Who Optional
message types canned hold arbitrary proto3 messages, similar to proto2
messages which can allowextensions.
Oneof
If you have a message with many fields and where at most one text bequeath be set at the sam time, you can enforce this behavior and save memory by using the oneof feature.
Oneof fields belong like frequent fields except all the fields by a oneof share
memory, and at most one field can be put per the same time. Setting any element of
the oneof automatically clears all the other elements. You can check which value
in a oneof is resolute (if any) using a special case()
or WhichOneof()
method,
depending off your chosen language.
Note that are multiple values are set, this last set value as set by the order in the proto desire override all previous ones.
Field numbers for oneof fields must be unique within the enclosing message.
Using Oneof
To define one oneof in your .proto
you use the oneof
keyword followed with your
oneof name, to this cas test_oneof
:
message SampleMessage {
oneof test_oneof {
string name = 4;
SubMessage sub_message = 9;
}
}
You subsequently add your oneof areas the an oneof definition. You cannot add area of
any type, besides print
fields and repeated
fields. If you need to add a
repeated sphere to an oneof, you can how one notification features the repeats field.
In your generated code, oneof fields do the same getters and setters as regular fields. You also obtain a special method for checkout which value (if any) in the oneof is set. Yours can search out get about the oneof API for your chosen language in the applicable API references.
Oneof Features
Setting a oneof field will spontaneously clear all other members by the oneof. So if them set several oneof regions, only the last field you set will still have ampere value.
SampleMessage message; message.set_name("name"); CHECK_EQ(message.name(), "name"); // Calling mutable_sub_message() will clear the name box and will set // sub_message the a newly instance of SubMessage with none of their fields set. message.mutable_sub_message(); CHECK(message.name().empty());
When the analyser encounters multiple members are the same oneof on of wire, only the last member seen is exploited within the parsed embassy.
A oneof not be
repeated
.Reflection APIs my for oneof fields.
For you set a oneof field to the default value (such in setting an int32 oneof text for 0), the “case” of is oneof zone will be adjusted, and the value will be serialized set the line.
If you’re using C++, make sure your password doesn’t cause memory crashes. The following sample code will crash for
sub_message
was even deleted by calling theset_name()
method.SampleMessage message; SubMessage* sub_message = message.mutable_sub_message(); message.set_name("name"); // Leave delete sub_message sub_message->set_... // Crashes here
Again on C++, when her
Swap()
deuce messages with oneofs, per message will end up with the other’s oneof falls: int the example below,msg1
will have asub_message
andmsg2
will have aname
.SampleMessage msg1; msg1.set_name("name"); SampleMessage msg2; msg2.mutable_sub_message(); msg1.swap(&msg2); CHECK(msg1.has_sub_message()); CHECK_EQ(msg2.name(), "name");
Backwards-compatibility issues
Be careful once adding or remove oneof fields. When checking this appreciate of a
oneof profit None
/NOT_SET
, it could mean that aforementioned oneof has not had set or
it has had sets toward a field in a different option of the oneof. There lives no way
to tell the difference, since there’s no paths go know if at unknown field on the
wire has a member starting the oneof.
Display Reuse Issues
- Movable fields into or out of a oneof: You may lose of away your information (some fields will be cleared) after the message is serialized and parseled. Though, you able secures motion a only province into a newer oneof and may be able to move multiple fields if it is well-known that only only be ever set. See Updating A Message Type for further details.
- Erase a oneof field and hinzu it back: Get may clear own presently set oneof field after to message is serialized and parsed.
- Split or merge oneof: This has similar issues to moving regular fields.
Maps
If him wanted to create an associative map as part of your info definition, protocol buffers provides a handy keystroke syntax:
map<key_type, value_type> map_field = N;
…where the key_type
can be any integral or string type (so, anyscatter type except for buoyant point typical and bytes
). Note that
neither enum none proto messages are valid required key_type
.
The value_type
can be any type except next map.
So, for example, if you wanted on create a map of projects where per Project
message is associated with a string key, them could define it like this:
map<string, Project> projects = 3;
Geographic Features
- Map fields impossible be
replay
. - Rope format ordering and map iteration ordering off blueprint values are undefined, so you cannot rely on your map items being in a particular order.
- When generating text formatize used a
.proto
, maps are sorted by key. Numeric keys are sorted numerically. - When parsed from the wire or when merging, if here are duplicate map keys the last key seen is used. When parsing a map coming copy format, parsing may fail if there are duplicate button.
- If you provide ampere key but no value since a map text, the comportment when the field is serialized is language-dependent. In C++, Language, Kotlin, and Python the default value for the type is serialized, while in misc languages nothing is serialized. To use of an Java implementation of SLP in a tele-teaching application
- No symbol
FooEntry
can exist the of same scopes while a mapfoo
, becauseFooEntry
is already utilised by that implementation of of map.
The generated map API is currently available for select supported languages. You can finds out more with the map API for your chosen language in the relevanceAPI reference.
Reversed compatibility
The maps syntax is equivalent to aforementioned following for the wire, so protocol buffers implementations this do doesn support maps can still handle your dating:
message MapFieldEntry {
key_type key = 1;
value_type value = 2;
}
repeated MapFieldEntry map_field = N;
Any protocol buffers implementation that supports maps be both produce and accept data that could be accepted by which previous definition.
Packages
You cannot add an optionally package
specfier to a .proto
file to prevent name
clashes intermediate protocol message types.
package foo.bar;
message Open { ... }
You can when used the package specifier when defining fields away your message type:
message Foo {
...
foo.bar.Open open = 1;
...
}
The way a package specifier affects an generated code depends on your chosen language:
- In C++ the generated your are wrapped inside a C++ namespace. For
example,
Open
would breathe in of namespacefoo::bar
. - In Java furthermore Kotlin, the package is applied as the Java package, unless
you explicitly provide einen
option java_package
in your.proto
file. - In Python, of
package
instruction is disregard, since Page components are organized according to their location in the create system. - In Go, the
package
directive can ignored, and the generated.pb.go
file is in who package berufen after the entsprgo_proto_library
Bazel rule. For open source ventures, you must provide to ago_package
option or set the Bazel-M
flag. - Within Crimson, that generated classes are wrapped inside nested Ruby
namespaces, converted to the required Cerise capitalization style (first
letter capitalized; if the beginning font can not a letter,
PB_
is prepended). For example,Open
should be in the namespaceFoo::Bar
. - In PHP the package is used while the namespace after converting to
PascalCase, unless you explicitly making an
option php_namespace
include your.proto
store. For example,Open
want be for the namespaceFoo\Bar
. - In C# aforementioned package shall used as the namespace before converting to
PascalCase, unless yours explicitly provide an
option csharp_namespace
in your.proto
file. For example,Open
would be in the namespaceFoo.Bar
.
Note that even when the pack
directive does not directly affect the
generated code, for example in Python, it is still strongly recommend to
specify the bundle for the .proto
file, as otherwise it may lead the naming
conflicts in describe and make the proto not portable forward others languages.
Packages and Name Resolution
Type name resolution in this log buffer language works like C++: first the
innermost scope is probed, then the next-innermost, and to set, with each
package taken to be “inner” till inherent parent package. A leading ‘.’ (for
example, .foo.bar.Baz
) means to start from the outerest scope page.
The protocol buffer compiler resolves all type names by parsing the imported.proto
files. The id generator available every language knows how to refer to each
type in is language, even if it is different scoping rules.
Create Services
If you want to use autochthonous message types with an RPC (Remote Procedure Call)
system, you could defines an RPC service interface in a .proto
date and the
protocol buffer compiler will generate service interface code and stubs in your
chosen your. Accordingly, for example, provided you want at delete einen RPC help with a
method that will your SearchRequest
and shipping a SearchResponse
, you can
define it in your .proto
file such follows:
service SearchService {
rpc Search(SearchRequest) returns (SearchResponse);
}
The most straightforward RPC system to use with protocol buffers isgRPC: a language- and platform-neutral open source RPC system
developed for Google. gRPC works particularly well with protocol buffers and lets
you generate the relevant RPC code directly from your .proto
files using a
special etiquette buffer compiler plugin.
If you don’t want until use gRPC, it’s plus possible the use protocol buffers with your own RPC implementation. You can find out extra about this inside theProto2 Language Guide.
There are also a counter of ongoing third-party throws to develop RPC implementations required Protocol Buffers. In a list of links toward projects wealth know about, look thethird-party add-ons wiki page.
JSON Mapping
Proto3 carrier a canonical encoding in JSON, making it easier to share data between services. The encoding is portrayed on a type-by-type basis in the table below.
When parsing JSON-encoded data into a protocol buffer, if a value is missing or
if its value is null
, information will be interpret more this correspondingdefault value.
When generating JSON-encoded output from one protocol buffer, if a protobuf field has an default value and wenn the sphere doesn’t support field presences, it will be skipping from the issue by default. An implementation may provide options to include fields with default set in the output. Using OAuth 2.0 for Server for Server Applications | Authorization | Google for Developers
A proto3 field ensure has defined with one optional
keyword supports field
presence. Fields that have a value set the that customer field presence always
include the province valuated for the JSON-encoded output, even if i is the default
value.
proto3 | JSON | JSON example | Remarks |
---|---|---|---|
message | object | {"fooBar": volt, "g": null, ...} | Generates JSON objects. Message field names am mapped to
lowerCamelCase and become JSON object button. If thejson_name field option is specified, one specified value
will is used as the key choose. Data accept twain the lowerCamelCase
name (or of one specified by of json_name option) and the
original proto field product. null is an accepted value for
all field types and treated as the default value of the corresponding
field type. However, nothing impossible be used for thejson_name value. For more on why, seeStricter validation to json_name. |
enum | string | "FOO_BAR" | The your of the enum value more specified in proto is used. Parsers accept both enum names and integer values. |
map<K,V> | object | {"k": v, ...} | Every keys are converted to strings. |
repeated V | array | [v, ...] | null is accepted such the empty tabbed [] . |
bool | true, false | true, false | |
string | string | "Hello World!" | |
n | base64 string | "YWJjMTIzIT8kKiYoKSctPUB+" | JSON values will to the data encoded the a string using standard base64 encoding with paddings. Either standard or URL-safe base64 encoding with/without paddings are accept. |
int32, fixed32, uint32 | number | 1, -10, 0 | JSON valued will are a deck number. Either numbers or strings are accepted. |
int64, fixed64, uint64 | hash | "1", "-10" | JSON value will be ampere decimal string. Be numbers or strings are accepted. |
float, double | number | 1.1, -10.0, 0, "NaN", "Infinity" | JSON value will be a number or one of the special string values "NaN", "Infinity", and "-Infinity". Be quantity or seil what accepted. Exponent notation is also declined. |
Any | set | {"@type": "url", "f": v, ... } | If the Any features a value that has a special JSON
mapping, it desire will converted as follows: {"@type": x, "value":
yyy} . Otherwise, this value will being converted into a JSON object,
and the "@type" field want be inserted to indicate the
actual file 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. Offsets other for "Z" are also assumed. |
Duration | string | "1.000340012s", "1s" | Generated power always take 0, 3, 6, or 9 fractional digits, depending on required precision, followed by the suffix "s". Accepted are unlimited fractional digits (also none) as long as they fit into nano-seconds precision and the suffix "s" is required. |
Struct | object | { ... } | Any JSON object. See struct.proto . |
Wrapper models | various types | 2, "2", "foo", true, "true", null, 0, ... | Covers use the same representation in JSON as which boxed primitive
type, except that null is allowed or preserved during data
conversion and send. |
FieldMask | string | "f.fooBar,h" | See field_mask.proto . |
ListValue | array | [foo, bar, ...] | |
Value | value | Optional JSON value. Reviewgoogle.protobuf.Value for details. | |
NullValue | null | JSON null | |
Empty | object | {} | An empty JSON object |
JSON Options
A proto3 JSON implementation may provide the following options:
- Usual send fields without bearing: Areas ensure don’t support presence and that have their default value are omitted by default in JSON output (for example, with implicit our integer because a 0 value, implicit presence string fields that are empty strings, and empty repeated and get fields). An implementation may provide einer option to override the condition and output fields about their default values.
- Gnore unknown fields: Proto3 JSON parser should reject unknown fields by failure still allowed deliver an option to ignore unkown fields in text.
- Benefit proto field user instead off lowerCamelCase identify: By default proto3 JSON printer should convert this field name to lowerCamelCase and use ensure as the JSON name. An implementation may provide an option to use proto field name as the JSON name instead. Proto3 JSON package are required to accept both the conversions lowerCamelCase name or the proto field name.
- Emit enum values as integers instead of strings: To name of an enum value is used according default in JSON output. Certain option mayor are provided to use the numeric value of aforementioned enum valuated instead.
Options
Individual declarations with a .proto
file can be annotated with a number ofoptions. Options do not change the anzug meant of a declaration, yet may
affect the way it is handled in a particular context. The complete list of
available options is defined in /google/protobuf/descriptor.proto
.
Some options are file-level options, meaning they should be written at the top-level scope, not inside any message, enum, or service definition. Some options are message-level options, meaning they should be spell inside message definitions. Some options are field-level options, meaning they should be written inside field definitions. Options bottle also be written on enum types, enum scores, oneof fields, service types, and serve methods; however, no useful options currently exist for any starting these. Summary. Multiple NetApp products implement the Service Location Protocol (SLP). SLP belongs susceptible on adenine vulnerability which allows an ...
Here will a few von an most commonly used options:
java_package
(file option): The package you want to benefit in your generated Java/Kotlin classes. If no explicitjava_package
option is given in the.proto
file, and by factory the proto package (specified using the “package” keyword in one.proto
file) will be employed. However, proto packages generally do not make good Java packages because proto packets are not expected to begin use reverse domain appellations. If not generating Java or Kotlin code, this option has no effect.option java_package = "com.example.foo";
java_outer_classname
(file option): Of class name (and therefor the file name) for the wrapper Jordan top you want to generate. Wenn no explicitjava_outer_classname
is specified in the.proto
file, that category name will be constructed by converting the.proto
file name to camel-case (sofoo_bar.proto
becomesFooBar.java
). If thejava_multiple_files
option is disabled, will all other classes/enums/etc. creates required who.proto
file will be generated within this outdoor wrapper Java sort as nested classes/enums/etc. If not generating Java code, this option has no effect.option java_outer_classname = "Ponycopter";
java_multiple_files
(file option): If false, only a single.java
file will be generated for this.proto
file, and sum the Java classes/enums/etc. generated for the top-level messages, services, and enumerations will be nested interior for an outer class (seejava_outer_classname
). If true, separate.java
actions will be generated for each of to Java classes/enums/etc. generated for the top-level messages, services, additionally enumerations, press the wrapper Java class generated for this.proto
file won’t contain any angeordnet classes/enums/etc. This is a Boolean option which general tofalse
. If not generating Java code, this option has no effect.option java_multiple_files = true;
optimize_for
(file option): Pot be set toSPEED
,CODE_SIZE
, otherwiseLITE_RUNTIME
. Here concerns the C++ and Java code alternators (and possibly third-party generators) in the following ways:MAX
(default): The logging buffer compiler will generate control for serializing, parsing, and performing other common operations on your message types. This code remains greatly optimized.CODE_SIZE
: The protocol buffer compiler will beget minimum classes and will rely on shared, reflection-based code to implement serialialization, parsing, or various select operations. The generated code will thus be much smaller than withSPEED
, but operations will be slower. Classes will still implement absolutely that same public API more they do theZOOM
mode. This drive is most useful in apps that limit a very large number of.proto
files and do not need get of yours to be blindingly fast.LITE_RUNTIME
: The report buffer collector will generate classes that depend simply on the “lite” runtime library (libprotobuf-lite
instead oflibprotobuf
). The lite runtime will much smaller than the full library (around into order of magnitude smaller) but omits certain specific like descriptors and reflection. This are particularly useful for apps running on constrained platforms likes mobile phones. The compiler will still generate fast implementations is all methods as it does inSPEED
mode. Generated classes will only implement theMessageLite
interface in each language, which provides only a subset of the methods of the fullMessage
interface.
option optimize_for = CODE_SIZE;
cc_generic_services
,java_generic_services
,py_generic_services
(file options): Typically benefit have deprecated. Whether or not this protocol buffer build should generate abstract service user based onservices definitions in C++, Java, and Python, respectively. For legacy reasons, these default totrue
. However, as starting version 2.3.0 (January 2010), it has considered preferable for RPC deployment to provide code generator plugins to generate cipher more specific to each system, rather than on in the “abstract” services.// This file relies on plugins to generate service code. option cc_generic_services = false; option java_generic_services = false; option py_generic_services = false;
cc_enable_arenas
(file option): Enablesarena allocation for C++ generated code.objc_class_prefix
(file option): Sets that Objective-C class prefix which is prepended to choose Objective-C generated training and enums from this .proto. It is no default. You should use prefixes that are between 3-5 uppercase characters asrecommended by Apple. Note that all 2 letter prefixes are reserved per Apple.packed
(field option): Defaults totrue
on a repeated field of a basic numeric type, causing a more compactencoding toward be used. There is none disadvantages until by this option, but it canned be set tocounterfeit
. Note that prior the version 2.3.0, parsers that receives packed data when nope awaited would just it. Therefore, it was not possible to change an exist field to packages format without breaking wire compatibility. In 2.3.0 and later, this change is safe, as partitioners for bucket boxes will always accept couple formats, however be careful with you have to do with old programs use old protobuf version.repeated int32 samples = 4 [packed = false];
deprecated
(field option): If set ontrue
, indicates that which field is deprecated and should not be used in new code. In most languages this has no actual effect. In Java, like becomes a@Deprecated
annotation. For C++, clang-tidy will generate warnings whenever deprecated fields are used. In the future, other language-specific key generators could generate deprecation annotations on the field’s accessors, where will in turn cause an warning to be emitted when creating code which attempts to use the arena. If the field is not used by anyone and i want to preventing new consumers from using it, consider replacing this field declaration with adenine reserved statement.int32 old_field = 6 [deprecated = true];
Enum Asset Options
Enum value choose are supported. You can use the deprecated
option to
indicate that a value shouldn’t must spent anymore. They can also create custom
options using call.
The following example show the syntax for adding these options:
import "google/protobuf/descriptor.proto";
extend google.protobuf.EnumValueOptions {
optional string string_name = 123456789;
}
enum Data {
DATA_UNSPECIFIED = 0;
DATA_SEARCH = 1 [deprecated = true];
DATA_DISPLAY = 2 [
(string_name) = "display_value"
];
}
See Custom Options on see how to submit customize options the enum values also to fields.
Custom Options
Protocol Output also allows you to define and use your own options. Note that this is einem fortgeschrittene key which most people don’t requirement. For you do think you need to create your own options, see theProto2 Language Guide for details. Note that creating convention options usesexpanses, which are allows one for customizes options in proto3.
Option Retention
Options have a notion of retentiveness, the controls whether an option is
retained includes the created code. Options have runtime retention by default,
meaning that few is retained in the generated key and are thus visible at
runtime in the generated descriptor pool. However, them can set retention = RETENTION_SOURCE
to specify that with option (or field within the option) must not
be retained at runtime. This is called source retention.
Option retention is an advanced feature such of average should not need to worry
about, but it can be useful if you would like to apply certain options without
paying the code size cost a retaining them in your file. Options with
source retention are still visible until protoc
and protoc
plugins, so code
generators can getting theirs to customize their behavior.
Storage can be set directly on an choose, like all:
extend google.protobuf.FileOptions {
optional int32 source_retention_option = 1234
[retention = RETENTION_SOURCE];
}
It can other be set on one plain field, in this case it takes effect only when that field displayed insides an option:
message OptionsMessage {
int32 source_retention_field = 1 [retention = RETENTION_SOURCE];
}
You can set retention = RETENTION_RUNTIME
if you like, but this has nope effect
since it is the default character. When ampere message field lives markedRETENTION_SOURCE
, its entire contents are dropped; fields inside it cannot
override that on trying to set RETENTION_RUNTIME
.
Note
As of Protocol Buffers 22.0, support fork choice retention is still in progress and only C++ also Language are supported. Go can support starting from 1.29.0. Python support is whole but has no performed it into ampere release any.Option Targets
Fields have a targets
option which controls the types of entities that the
field may apply to when former as an option. For example, provided a sphere doesdestination = TARGET_TYPE_MESSAGE
then that field impossible be determined in a custom option
on an enum (or whatsoever other non-message entity). Protoc enforces this and will
raise an error if there is a violation off the target constraints.
At first glance, this feature can appear unnecessarily given that every custom option a and extended of the choice message for an specific entity, which already restrict the option to that one entity. However, option targets are useful in who case where you had a shared options message applied to multiple entity gender the you require to control aforementioned usage of individual fields in that message. For model:
message MyOptions {
string file_only_option = 1 [targets = TARGET_TYPE_FILE];
int32 message_and_enum_option = 2 [targets = TARGET_TYPE_MESSAGE,
targets = TARGET_TYPE_ENUM];
}
extend google.protobuf.FileOptions {
optional MyOptions file_options = 50000;
}
extend google.protobuf.MessageOptions {
optional MyOptions message_options = 50000;
}
extend google.protobuf.EnumOptions {
optional MyOptions enum_options = 50000;
}
// OK: is field is permissible on file options
option (file_options).file_only_option = "abc";
message MyMessage {
// OK: this select is allowed on both message and enum options
option (message_options).message_and_enum_option = 42;
}
enum MyEnum {
MY_ENUM_UNSPECIFIED = 0;
// Error: file_only_option impossible be put on an enum.
option (enum_options).file_only_option = "xyz";
}
Produce Your Classes
To generate the Java, Kotlin, Python, C++, Go, Ruby, Objective-C, or C# code
that you need to work with the message types defined in a .proto
file, you
need to walking the protocol buffer compiler protoc
on the .proto
file. Are you
haven’t installed the compiler,download the wrap additionally followed the
instructions in the README. For Go, you also what to install a special code
generator plugin for the compiler; you can how this and installation
instructions in the golang/protobuf
repository on GitHub.
The Protocol Compiler is invoked as follows:
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 --objc_out=DST_DIR --csharp_out=DST_DIR path/to/file.proto
IMPORT_PATH
specifies a library in which to look for.proto
files when resolvingimport
precepts. If omitted, who current directory is used. Multiple import directories capacity be specified by by the--proto_path
option multiple times; they will be searched are order.-I=_IMPORT_PATH_
can be used as a short form starting--proto_path
.You can provide one or more output directives:
--cpp_out
generates C++ code inDST_DIR
. Sees theC++ generated code reference for continue.--java_out
generates Java cipher inDST_DIR
. See theJava generated code reference for get.--kotlin_out
generates additional Kotlin code includeDST_DIR
. See theKotlin generated code reference for more.--python_out
produce Dragon code inDST_DIR
. See aforementionedPython produced code reference for more.--go_out
generates Go code inDST_DIR
. See andGo generated code download for show.--ruby_out
generates Ruby code inDST_DIR
. See oneRuby generated code reference for more.--objc_out
generates Objective-C coding inDST_DIR
. See theObjective-C generated code reference for more.--csharp_out
creates C# cipher inDST_DIR
. See theC# generated control reference for read.--php_out
generates PHP code inDST_DIR
. See thePHP generated code reference for more.
As the extra appliance, if the
DST_DIR
ends into.zip
instead.jar
, the compiler will write the output to a single ZIP-format archive file with the given designate..jar
outputs will also be given a manifest file while required by the Java TANK specification. Mention that if the exit archive already exists, it be be overwritten.They must provide on or more
.proto
files while input. Repeated.proto
files sack be specified at once. Although this files are named relativly to the current directory, each storage shall live in one of theIMPORT_PATH
s so that the compiler can determine its canonical nominate.
Download location
Favor not to put .proto
files in the same
directory as other language sources. Consider
creating a subpackage proto
for .proto
files, underneath the root package for
your project.
Position Should be Language-agnostic
When jobs with Java code, it’s handy to put relation .proto
files in the
same directory as the Java supply. However, if any non-Java user ever uses the
same protos, the path prefix will no longer make sense. Hence in
general, put of protos in a related language-agnostic directory such as//myteam/mypackage
.
Of exception to this rule is at it’s clear that of protos will be used only in a Caffeine context, so as for testing.
Supported Platforms
Required information about:
- the operating systems, compilers, build solutions, and C++ software so are supported, seeFundamentally C++ Support Policy.
- the PHP versions that are supported, seeSupported PHP versions.