PB reads standard protobuf FileDescriptorSet images — the same artifact any
protobuf toolchain can produce. There is no PB-specific protoc plugin and no
generated Elixir source.
With protoc
protoc --descriptor_set_out=schema.binpb --include_imports your.proto
--descriptor_set_outwrites the binaryFileDescriptorSet.--include_importsmakes the set self-contained by including imported.protofiles. Always pass it unless you have a specific reason not to — PB needs every referenced type present to resolve fields.
Load and compile it:
{:ok, descriptor_set} = PB.decode_descriptor_set(File.read!("schema.binpb"))
schema = PB.compile(descriptor_set)A bang variant PB.decode_descriptor_set!/1 is also available.
With buf
If you use buf, produce a descriptor set (an "image") with:
buf build -o schema.binpb
buf images are FileDescriptorSet-compatible and load the same way.
Custom representation options in proto source
If you want to declare Elixir representation (struct:, unwrap:, identity
oneofs) directly in your .proto files rather than at compile time, import
elixir/pb/v1/options.proto and set the elixir.pb.v1 custom options. Those options
travel inside the descriptor set and are picked up by PB.compile/2. See
Decoding into structs for the option surface.
Embedding at compile time
Loading the descriptor set at runtime is fine for dynamic schemas. For a stable
schema, embed it into a module at compile time with use PB.Schema — see
Schema modules.