+++ title = "ProtoCBOR Format" weight = 62 description = "Covers how to use the Protobuf to CBOR conversion utilities." type = "docs" +++
Protobuf supports a canonical encoding in CBOR, making it easier to share data with systems that do not support the standard protobuf binary wire format and have processing constraints that prefer more concise encoding.
ProtoCBOR Format is not as efficient as protobuf wire format. Like ProtoJSON, the converter uses more CPU to encode and decode messages and encoded messages usually consume more space. CBOR is a schemaless type-length-value (TLV) encoding, so it incurs more interpretive overhead than the standard wire format.
The encoding is described on a type-by-type basis in the table later in this topic.
When parsing CBOR-encoded data into a protocol buffer, if a value is missing or if its value is null
, it will be interpreted as the corresponding default value.
When generating CBOR-encoded output from a protocol buffer, if a protobuf field has the default value and if the field doesn't support field presence, it will be omitted from the output by default. An implementation may provide options to include fields with default values in the output.
ProtoCBOR does support field presence. A message type field in any edition of protobuf supports field presence and if set will appear in the output. Proto3 implicit-presence scalar fields will only appear in the CBOR output if they are not set to the default value for that type.
Protobuf | CBOR | CBOR example (diagnostic notation) | Notes |
---|---|---|---|
message | map | {/fooBar/ 0: v, /g/ 1: null, ...} |
Generates CBOR maps. Message field numbers are represented as CBOR `int` and become CBOR map keys.
null is an accepted value for all field types and treated as the default value of the corresponding field type.
|
enum | int | 5 |
The enum value as specified in proto is used and sent as a CBOR-encoded int. |
map<K,V> | map | { * K => V} |
All keys are converted to their CBOR encodings. |
repeated V | definite-length array | [v, ...] |
null is accepted as the empty list [] . |
bool | true, false | true, false |
|
string | string | "Hello World!" |
|
bytes | bstr | h'deadc0de' |
CBOR value will be the data encoded as a byte string. |
int32, int64, uint32, uint64 | int | 1, -10, 0 |
CBOR value will use its variable length encodings for integers, which account for the first 60 entries of the initial byte jump table. Unsigned integers do not use the latter 32 entries of the initial 60 entries of the initial byte jump table. |
fixed32 | tagged little endian | 1, 10, 0 |
CBOR value is #6.70(bytes .size 4) encoded as little-endian. |
fixed64 | tagged little endian | 1, 10, 0 |
CBOR value is #6.71(bytes .size 8) encoded as little-endian. |
sfixed32 | tagged little endian | 1, -10, 0 |
CBOR value is #6.78(bytes .size 4) encoded as little-endian. |
sfixed64 | tagged little endian | 1, -10, 0 |
CBOR value is #6.79(bytes .size 8) encoded as little-endian. |
float, double | float, double | 1.1, -10.0, 0, NaN, Infinity |
CBOR value will be the smallest lossless encoding of the floating point number, choosing between simple value, half-precision, single-precision, or double-precision. |
Any | Generic value CBOR |
27([TypeURL, value]) |
The URL of a binary `google.protobuf.Type` paired with the deserialized CBOR representation. Check google.protobuf.Any for details. |
Timestamp | #6.0(string) | 0("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 than "Z" are also accepted. |
Duration | #6.1002(map) | 1002({1: 17020, -9: 900000}) |
A duration in RFC9581 format, limited to durations representable in `google.protobuf.Duration`. |
Struct | map |
{ int => any } |
Any CBOR map with integer keys and respectively constrained values. See struct.proto . |
Wrapper types | various types | 2, "2", "foo", true, "true", null, 0, ... |
Wrappers use the same representation in CBOR as the wrapped primitive
type, except that null is allowed and preserved during data
conversion and transfer.
|
FieldMask | string | "f.fooBar,h" |
See field_mask.proto . TODO |
ListValue | array | [foo, bar, ...] |
Definite-length array. |
Value | value | A CBOR value that is JSON-like, but structs have integer keys. Check google.protobuf.Value for details. | |
NullValue | null | CBOR null | |
Empty | map | {} |
An empty CBOR map, but represented differently as an Any value. |
A conformant protobuf CBOR implementation may provide the following options:
-
Ignore unknown fields: The protobuf CBOR parser should reject unknown fields by default but may provide an option to ignore unknown fields in parsing.
-
Emit validation code: For registered CBOR tags that have further validation requirements, the protobuf CBOR message should have validation methods emitted.