Skip to content

google.protobuf.Value and google.protobuf.Struct cover data that isn't a Protobuf message at all, just arbitrary JSON you don't want to model up front. Any, by contrast, carries a Protobuf message whose type isn't known until runtime.

A Value can be a null, a number, a string, a boolean, a struct of further values, or a list of them. Those six cases are exactly JSON's own types: null, number, string, boolean, object, and array.

A field typed as Value or Struct has no schema checking, so generated code can't tell you what's inside. Keep them for the places that need them, such as integrating with a schemaless NoSQL database or passing along a metadata blob nobody wants to write a schema for.

Any, Value, and Struct all fall under Well-Known Types. The Types reference lists the rest, including Timestamp and Duration.

Compare with a schema field: here the names theme, retries, and beta are all in the payload.

schema.proto
edition = "2024";

package demo.v1;

import "google/protobuf/struct.proto";

message Config {
  google.protobuf.Struct settings = 1;
}
Input JSON (editable)
{
  "settings": {
    "theme": "dark",
    "retries": 3,
    "beta": true
  }
}
ProtoJSON

Compiling the schema...

Next

Editions

What Protobuf editions are, how they replace proto2 and proto3 syntax, and how features migrate schemas incrementally without breaking the wire format.