Lesson 5 / 25
Enums, oneof, maps and Well-Known Types
Modelling richer data.
Beyond scalars
Enums must have a zero value, conventionally *_UNSPECIFIED = 0, which is the default when the field is unset. repeated makes a list, map<string, string> a map, and oneof says exactly one of several fields is set. Well-known types from google/protobuf cover common needs: Timestamp, Duration, FieldMask (partial updates), Empty, Struct and wrapper types. Import other proto files to share messages.
Enums, oneof and well-known types
Protobuf.
import "google/protobuf/timestamp.proto";
enum OrderStatus {
ORDER_STATUS_UNSPECIFIED = 0;
ORDER_STATUS_PENDING = 1;
ORDER_STATUS_PAID = 2;
ORDER_STATUS_SHIPPED = 3;
}
message Payment {
oneof method {
Card card = 1;
string upi_id = 2;
string wallet_token = 3;
}
google.protobuf.Timestamp paid_at = 4;
map<string, string> labels = 5;
}
message Card {
string last4 = 1;
string network = 2;
}Prefix enum values with the enum name
Enum values share a namespace within a package, so ORDER_STATUS_PAID avoids clashes with PAYMENT_STATUS_PAID.
Quick check: Why should an enum start with an UNSPECIFIED value of 0?
- Protobuf forbids other numbers
- Zero is the default for unset fields, so it should mean "not set" rather than a real state
- It makes messages smaller
- It sorts enums alphabetically
Answer
Zero is the default for unset fields, so it should mean "not set" rather than a real state — Defaults should be safe.