SkillByAIOpen interactive version →

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.