#readwise
# Protocol Buffers Language Guide

## Metadata
- Author: [[protobuf.dev]]
- Full Title: Protocol Buffers Language Guide
- URL: https://protobuf.dev/programming-guides/proto3/
## Summary
The Protocol Buffers Language Guide explains how to use the proto3 version of Protocol Buffers in your projects. It covers how to define message types, assign unique field numbers, and specify field characteristics like cardinality. The guide also discusses how to handle reserved field numbers and import definitions from other .proto files. Finally, it explains how to generate code for different programming languages using the protocol buffer compiler.
## Highlights
Don’t change the field numbers for any existing fields. “Changing” the field number is equivalent to deleting the field and adding a new field with the same type. ([View Highlight](https://read.readwise.io/read/01jdvyyen3xyas49j8jqvjpy9m))
---
If you add new fields, any messages serialized by code using your “old” message format can still be parsed by your new generated code. You should keep in mind the [default values](https://protobuf.dev/programming-guides/proto3#default) for these elements so that new code can properly interact with messages generated by old code. Similarly, messages created by your new code can be parsed by your old code: old binaries simply ignore the new field when parsing. ([View Highlight](https://read.readwise.io/read/01jdvyz3nvgecgg0kqygbh077d))
---
Fields can be removed, as long as the field number is not used again in your updated message type. You may want to rename the field instead, perhaps adding the prefix “OBSOLETE_”, or make the field number [reserved](https://protobuf.dev/programming-guides/proto3#fieldreserved), so that future users of your `.proto` can’t accidentally reuse the number. ([View Highlight](https://read.readwise.io/read/01jdvyzqnh75k0gfvchn59bfb8))
---
`int32`, `uint32`, `int64`, `uint64`, and `bool` are all compatible – this means you can change a field from one of these types to another without breaking forwards- or backwards-compatibility. If a number is parsed from the wire which doesn’t fit in the corresponding type, you will get the same effect as if you had cast the number to that type in C++ (for example, if a 64-bit number is read as an int32, it will be truncated to 32 bits). ([View Highlight](https://read.readwise.io/read/01jdvyzz0n9zma6fravd88ny8g))
---
`sint32` and `sint64` are compatible with each other but are *not* compatible with the other integer types. ([View Highlight](https://read.readwise.io/read/01jdvz04x47teeymzb22ngrkzn))
---
`string` and `bytes` are compatible as long as the bytes are valid UTF-8. ([View Highlight](https://read.readwise.io/read/01jdvz08thqetb0cp2j847xnzf))
---
Embedded messages are compatible with `bytes` if the bytes contain an encoded instance of the message. ([View Highlight](https://read.readwise.io/read/01jdvz0h0bcydd1c6mzb0nct6q))
---
`fixed32` is compatible with `sfixed32`, and `fixed64` with `sfixed64`. ([View Highlight](https://read.readwise.io/read/01jdvz14beaak97k92qvd0e47m))
---
For `string`, `bytes`, and message fields, singular is compatible with `repeated`. Given serialized data of a repeated field as input, clients that expect this field to be singular will take the last input value if it’s a primitive type field or merge all input elements if it’s a message type field. Note that this is **not** generally safe for numeric types, including bools and enums. Repeated fields of numeric types are serialized in the [packed](https://protobuf.dev/programming-guides/encoding#packed) format by default, which will not be parsed correctly when a singular field is expected. ([View Highlight](https://read.readwise.io/read/01jdvz1z69dyyjp98b2dve0xh9))
---
`enum` is compatible with `int32`, `uint32`, `int64`, and `uint64` in terms of wire format (note that values will be truncated if they don’t fit). However, be aware that client code may treat them differently when the message is deserialized: for example, unrecognized proto3 `enum` values will be preserved in the message, but how this is represented when the message is deserialized is language-dependent. Int fields always just preserve their value. ([View Highlight](https://read.readwise.io/read/01jdvz2jyg31mkyg3wa6k3x5j9))
---
Changing a single `optional` field or extension into a member of a **new** `oneof` is binary compatible, however for some languages (notably, Go) the generated code’s API will change in incompatible ways. For this reason, Google does not make such changes in its public APIs, as documented in [AIP-180](https://google.aip.dev/180#moving-into-oneofs). With the same caveat about source-compatibility, moving multiple fields into a new `oneof` may be safe if you are sure that no code sets more than one at a time. Moving fields into an existing `oneof` is not safe. Likewise, changing a single field `oneof` to an `optional` field or extension is safe. ([View Highlight](https://read.readwise.io/read/01jdvz4155fw53s68463je915c))
---
Changing a field between a `map<K, V>` and the corresponding `repeated` message field is binary compatible (see [Maps](https://protobuf.dev/programming-guides/proto3#maps), below, for the message layout and other restrictions). However, the safety of the change is application-dependent: when deserializing and reserializing a message, clients using the `repeated` field definition will produce a semantically identical result; however, clients using the `map` field definition may reorder entries and drop entries with duplicate keys. ([View Highlight](https://read.readwise.io/read/01jdvz4xmw78j4s3aa6ygf3d3x))
---
If you have a message with many singular fields and where at most one field will be set at the same time, you can enforce this behavior and save memory by using the oneof feature.
Oneof fields are like optional fields except all the fields in a oneof share memory, and at most one field can be set at the same time. Setting any member of the oneof automatically clears all the other members. You can check which value in a oneof is set (if any) using a special `case()` or `WhichOneof()` method, depending on your chosen language.
Note that if *multiple values are set, the last set value as determined by the order in the proto will overwrite all previous ones*. ([View Highlight](https://read.readwise.io/read/01jdvygpzc1fa0qc00y6pe07md))
---
Be careful when adding or removing oneof fields. If checking the value of a oneof returns `None`/`NOT_SET`, it could mean that the oneof has not been set or it has been set to a field in a different version of the oneof. There is no way to tell the difference, since there’s no way to know if an unknown field on the wire is a member of the oneof. ([View Highlight](https://read.readwise.io/read/01jdvynnex78mk4wkwke41rk1v))
---
**Move singular fields into or out of a oneof**: You may lose some of your information (some fields will be cleared) after the message is serialized and parsed. However, you can safely move a single field into a **new** oneof and may be able to move multiple fields if it is known that only one is ever set. ([View Highlight](https://read.readwise.io/read/01jdvypbq7310qwd7pqxjn6387))
---