There are 6 field types in Protocol Buffers:
Every field is one of those types.
An optional field is a field that may or may not have a value set.
When no value is set, this is indicated as null
in Mouse Melon.
optional
string
name = 1
;
In Proto 2 it is possible to give a default value to optional fields:
optional
string
name = 1
; [default
= "bla"
]
When parsing data, the Protocol Buffer library will use this default value when no value is set.
The optional keyword was initially not in proto 3, but came back in version 3.15.
optional
string
name = 1
;
In edition 2023, the optional keyword disappeared and fields are optional by default.
string
name = 1
;
An required field is similar to an optional field, except that it must be present in the serialized data. If it is not, parsing will fail. (In Mouse Melon parsing will not fail when a required field is missing in the data, but a warning icon will notify the user of the missing field)
required
string
name = 1
;
Required fields are not supported in proto 3. Use an optional or implicit field instead.
In edition 2023, the required keyword disappeared. Required fields can still be made using the following syntax:
string
name = 1
[features.field_presence
= LEGACY_REQUIRED];
An implicit field is a field with a certain default value:
When a message is parsed, fields that are not present in the data will get this default value. When a message is saved, field that have this default value will not be written.
An implicit message field behaves the same as an optional message field. To emphasize that this field can be null, an implicit message field is always displayed as optional field in Mouse Melon.
Implicit fields are not supported in proto 2. Use an optional or required field instead.
string
name = 1
;
In edition 2023, implicit fields can be made using the following syntax:
string
name = 1
[features.field_presence
= IMPLICIT];
A repeated field is what would be called a list or array in most programming languages. It's default value is the empty list.
repeated
string
names = 1
;
Arrays of arrays are not supported in Protocol Buffers. If you need an array of arrays, put a repeated field in a message and repeat that message. When you have a two-dimensional (rectangular) array, you can also save the flattened array and add an int field with either the width or the height of the array.
If your data type is numeric, boolean or an enum, repeated fields come in two encodings: packed and expanded. Expanded was the initial format, but the packed format saves data more efficiently. Use the packed format unless you need compatibility with very old Protocol Buffers libraries that do not support it. Modern Protocol Buffer libraries should be able to read both packed and expanded data regardless of whether the field is declared as packed or expanded in the proto file. The choice between packed and expanded is only about how the field is saved.
In Proto 2, fields are expanded by default. To use packed fields, use this notation:
repeated
uint32
ids = 1
[packed
= true];
In Proto 3, fields are packed by default. To use expanded fields, use this notation:
repeated
uint32
ids = 1
[packed
= false];
In edition 2023, fields are packed by default. To use expanded fields, use this notation:
repeated
uint32
ids = 1
[features.repeated_field_encoding
= EXPANDED];
With oneof you can give a list of fields. At most one of those fields can be set.
This example gives a client the possibility to log in using either a user ID or a user name:
message
Login {
oneof
user {
uint32
user_id = 1
;
string
user_name = 2
;
}
string
password = 3
;
}
A map is a collection of key/value pairs, where each key occurs at most once. In Protocol Buffers, integers, booleans and strings can be used as map key. Any data type can be used as map value. Example:
map
<string
, uint32
> counters = 1
;
Field types cannot be combined, so it's not possible to have something like a repeated map or a map of maps. If you need such a combination, you'll have to wrap the inner type in a message. For repeated maps, this becomes:
message
MyMap {
map
<string
, string
> data = 1
;
}
repeated
MyMap maps = 1
;