Skip to content
protobuf.kmcd.dev

Descriptors

04_DESCRIPTORS

Descriptors

Descriptors are Protobuf schemas represented as Protobuf data. They power reflection, dynamic decoding, validation, and compiler plugin input.

Schemas Describing Schemas

When you run the Protobuf compiler (protoc), it doesn't just generate code. It can also output a binary representation of your schema called a FileDescriptorSet.

Fascinatingly, this FileDescriptorSet is itself a Protobuf message! Google defines a schema (descriptor.proto) that describes how to represent .proto files. This means you can use Protobuf tools to read and analyze Protobuf schemas dynamically at runtime.

Why is this useful?

Dynamic Decoding

Tools like this web explorer use descriptors to decode arbitrary binary data without generating static code.

Validation

Complex rule engines (like protovalidate) use descriptors to apply constraints dynamically.

Code Generation

Protoc plugins (the tools that generate your code) receive these descriptors as input. This is THE way that custom code generators are built.

DESCRIPTOR.PROTO (SNIPPET)
// The schema that describes a schema
message FileDescriptorSet {
  repeated FileDescriptorProto file = 1;
}

message FileDescriptorProto {
  optional string name = 1;
  optional string package = 2;
  repeated DescriptorProto message_type = 4;
  repeated EnumDescriptorProto enum_type = 5;
  // ...
}

message DescriptorProto {
  optional string name = 1;
  repeated FieldDescriptorProto field = 2;
  // ...
}

Try editing the schema below to see how the generated FileDescriptorSet changes in real-time.

SCHEMA_EDITOR (.proto)
edition = "2023";

package demo.v1;

import "buf/validate/validate.proto";

message User {
  string id = 1 [json_name = "uid"];
  string name = 2;
  uint32 age = 3 [(buf.validate.field).uint32.lt = 150];
  Role role = 4;

  enum Role {
    ROLE_UNSPECIFIED = 0;
    ROLE_USER = 1;
    ROLE_ADMIN = 2;
  }
}
Valid
DESCRIPTOR_OUTPUT

Correct compilation errors
to view descriptor