Skip to content

Say you don't know a message's type at compile time. That's the case Any is built for.

google.protobuf.Any embeds an arbitrary serialized Protobuf message along with a URL that identifies its type, something like type.googleapis.com/mypackage.MyMessage.

Serialize that to ProtoJSON, and the type identifier turns into a special @type property sitting next to the embedded message's own JSON fields. A parser reads that property first, and knows where to route the rest of the payload.

The bytes carry the type URL as a plain string plus the serialized Note. That URL is the size cost of Any.

schema.proto
edition = "2024";

package demo.v1;

import "google/protobuf/any.proto";

message Envelope {
  string kind = 1;
  google.protobuf.Any payload = 2;
}

message Note {
  string text = 1;
}
Input JSON (editable)
{
  "kind": "note",
  "payload": {
    "@type": "type.googleapis.com/demo.v1.Note",
    "text": "hello"
  }
}
ProtoJSON

Compiling the schema...

Next

The Value Type

Modeling schema-less, JSON-like data in Protobuf with google.protobuf.Value and Struct, and when to reach for them instead of Any.