Skip to content

A map field is a dictionary. The example uses string keys and string values for labels, integer keys for port numbers, and message values for entries that need more than one piece of data.

A key can be any integer type, a bool, or a string. Messages, enums, floats, and bytes can't be keys. A value can be any type, including another message, except another map or a repeated field; wrap those in a message if you need them.

Underneath, a map is a repeated message with a key field and a value field, so decoders written before maps existed can still read them. The Binary chapter shows the bytes.

Two entries, each written as its own little message on field 2. Entry order is not guaranteed to survive.

schema.proto
edition = "2024";

package demo.v1;

message Project {
  string name = 1;
  map<string, string> labels = 2;
  map<uint32, string> port_names = 3;
  map<string, Contributor> contributors = 4;
}

message Contributor {
  string name = 1;
  uint32 commit_count = 2;
}
Input JSON (editable)
{
  "name": "protobuf.com",
  "labels": {
    "team": "docs",
    "tier": "public"
  }
}
ProtoJSON

Compiling the schema...

Next

Oneof

Using oneof in Protobuf for mutually exclusive fields: tagged-union semantics, how setting one member clears the others, and modeling polymorphic data.