Embeds a compiled PB schema into a module at compile time.
This is the compile-time counterpart to the runtime flow of reading a
descriptor set, calling PB.decode_descriptor_set/1, and then
PB.compile/1. Runtime schema maps remain fully supported; use this
module when a schema is stable enough to travel with the compiled BEAM code.
Descriptor file
defmodule MyApp.Schema do
use PB.Schema, descriptor: "priv/proto/schema.binpb"
endThe descriptor file must be a binary google.protobuf.FileDescriptorSet, such
as one produced by:
protoc --descriptor_set_out=priv/proto/schema.binpb --include_imports your.protoRelative descriptor paths are resolved from the compiler working directory
(the Mix project root during normal Mix compilation). The generated module is
marked with @external_resource, so Mix recompiles it when the descriptor file
changes.
Add :projections to attach message-level adapters and structural term
representations to the embedded schema:
defmodule MyApp.Schema do
use PB.Schema,
descriptor: "priv/proto/schema.binpb",
projections: [
{:"google.protobuf.Timestamp", adapter: MyApp.Timestamp.adapter()},
{:"my.app.User", struct: MyApp.User},
{:"my.app.Wrapper", unwrap: :value, preserved_unknown_fields: :reject},
{:"my.app.Event", oneofs: [data: [representation: :identity]]}
]
endStructural projections can also be declared in proto source with the
elixir.pb.v1 custom options. Use compile-time :projections only when
attaching adapters or compiling overrides for third-party schemas or
generated descriptor sets you do not own.
Descriptor set map
For hand-authored schemas or tests, pass the decoded descriptor set map directly:
defmodule MyApp.Schema do
use PB.Schema,
descriptor_set: %{
file: [
%{
name: "greeter.proto",
package: :greeter,
syntax: :proto3,
message_type: [
%{
name: :HelloRequest,
field: [
%{name: :name, number: 1, type: :TYPE_STRING, label: :LABEL_OPTIONAL}
]
}
]
}
]
}
endGenerated API
A schema module exposes:
__pb_schema__/0— callback returning the embedded compiled schema.schema/0— public convenience alias for the callback.encode/2,3andencode!/2,3— callPB.encode/4andPB.encode!/4.encode_iodata/2,3andencode_iodata!/2,3— callPB.encode_iodata/4andPB.encode_iodata!/4for zero-copy iodata output.decode/2,3anddecode!/2,3— callPB.decode/4andPB.decode!/4.normalize/2,3andnormalize!/2,3— callPB.normalize/4andPB.normalize!/4.validate/2,3andvalidate!/2,3— callPB.Validate.validate/4andPB.Validate.validate!/4.
The top-level PB, PB.Validate, and PB.JSON entry points
accept the schema module directly in place of a compiled schema map.
Introspection
This module also exposes lookup helpers that return public PB.Schema.Info
structs — use these instead of reading the compiled-schema map directly:
list_messages/1,fetch_message/2,message!/2list_enums/1,fetch_enum/2,enum!/2list_services/1,fetch_service/2,service!/2list_extensions/1,fetch_extension/2,extension!/2
Every lookup accepts either a compiled schema map or a use PB.Schema
module. The bang variants raise PB.SchemaError (with kind: :unknown_* and
operation: :introspect) on miss; the fetch_* variants return
{:ok, info} | :error. The returned Info structs are the public stable
surface — the compiled-schema internals may change without notice.
Summary
Functions
Looks up an enum by fully-qualified name, raising PB.SchemaError with
kind: :unknown_enum if the enum is not in the schema.
Looks up an extension by fully-qualified name, raising PB.SchemaError with
kind: :unknown_extension if the extension is not in the schema.
Looks up an enum by fully-qualified name, returning {:ok, %PB.Schema.Info.Enum{}} or :error.
Looks up an extension by fully-qualified name, returning {:ok, %PB.Schema.Info.Field{}} or :error.
Looks up a message by fully-qualified name, returning {:ok, %PB.Schema.Info.Message{}} or :error.
Looks up a service by fully-qualified name, returning {:ok, %PB.Schema.Info.Service{}} or :error.
Returns the fully-qualified names of every enum in schema_source, sorted
alphabetically.
Returns the fully-qualified names of every extension in schema_source,
sorted alphabetically.
Returns the fully-qualified names of every message in schema_source,
sorted alphabetically.
Returns the fully-qualified names of every service in schema_source,
sorted alphabetically.
Looks up a message by fully-qualified name, raising PB.SchemaError with
kind: :unknown_message if the message is not in the schema.
Looks up a service by fully-qualified name, raising PB.SchemaError with
kind: :unknown_service if the service is not in the schema.
Functions
@spec enum!(PB.schema_source(), PB.enum_name()) :: PB.Schema.Info.Enum.t()
Looks up an enum by fully-qualified name, raising PB.SchemaError with
kind: :unknown_enum if the enum is not in the schema.
@spec extension!(PB.schema_source(), PB.extension_name()) :: PB.Schema.Info.Field.t()
Looks up an extension by fully-qualified name, raising PB.SchemaError with
kind: :unknown_extension if the extension is not in the schema.
@spec fetch_enum(PB.schema_source(), PB.enum_name()) :: {:ok, PB.Schema.Info.Enum.t()} | :error
Looks up an enum by fully-qualified name, returning {:ok, %PB.Schema.Info.Enum{}} or :error.
@spec fetch_extension(PB.schema_source(), PB.extension_name()) :: {:ok, PB.Schema.Info.Field.t()} | :error
Looks up an extension by fully-qualified name, returning {:ok, %PB.Schema.Info.Field{}} or :error.
@spec fetch_message(PB.schema_source(), PB.message_name()) :: {:ok, PB.Schema.Info.Message.t()} | :error
Looks up a message by fully-qualified name, returning {:ok, %PB.Schema.Info.Message{}} or :error.
@spec fetch_service(PB.schema_source(), PB.service_name()) :: {:ok, PB.Schema.Info.Service.t()} | :error
Looks up a service by fully-qualified name, returning {:ok, %PB.Schema.Info.Service{}} or :error.
@spec list_enums(PB.schema_source()) :: [PB.enum_name()]
Returns the fully-qualified names of every enum in schema_source, sorted
alphabetically.
@spec list_extensions(PB.schema_source()) :: [PB.extension_name()]
Returns the fully-qualified names of every extension in schema_source,
sorted alphabetically.
@spec list_messages(PB.schema_source()) :: [PB.message_name()]
Returns the fully-qualified names of every message in schema_source,
sorted alphabetically.
schema_source is either a compiled schema map or a module that
use PB.Schema.
@spec list_services(PB.schema_source()) :: [PB.service_name()]
Returns the fully-qualified names of every service in schema_source,
sorted alphabetically.
@spec message!(PB.schema_source(), PB.message_name()) :: PB.Schema.Info.Message.t()
Looks up a message by fully-qualified name, raising PB.SchemaError with
kind: :unknown_message if the message is not in the schema.
@spec service!(PB.schema_source(), PB.service_name()) :: PB.Schema.Info.Service.t()
Looks up a service by fully-qualified name, raising PB.SchemaError with
kind: :unknown_service if the service is not in the schema.