Behaviour for libraries that compile their own data into a PB schema, such as the protovalidate rules of pb_validate.
Plugins are listed in the :plugins option of PB.compile/2 and
use PB.Schema. Each entry is a module or a {module, opts} tuple:
PB.compile(descriptor_set, plugins: [MyPlugin, {OtherPlugin, mode: :strict}])Compiling
compile/2 receives the final, prepared schema, after projections and
runtime preparation, and returns it with the plugin's data added. Plugins run
in list order, so a plugin sees the data of the plugins listed before it. The
descriptor options of messages, fields, oneofs, and extensions are kept on
the prepared schema, so a plugin reads its configuration from them.
The compiled schema records which plugins compiled it, and with what options. When PB derives a new schema from a compiled one, such as narrowing it to a few root messages, it drops every recorded plugin's data and runs the plugins again on the result, so plugin data never describes a schema it no longer belongs to.
Where plugin data lives
A plugin stores its data under one key: its own module. That key may be set
on the schema map itself, on a message (an entry of the schema's :messages),
on a field or extension (an entry of a message's :fields_by_name or
:extensions_by_name, or of the schema's :extensions_by_name), on a oneof
(an entry of a message's :oneofs), and on an enum (an entry of the schema's
:enums):
schema = Map.put(schema, MyPlugin, %{built_at: now})
field = Map.put(field, MyPlugin, %{checks: checks})These are the only places PB looks when it drops plugin data. Other copies of
messages and fields in the prepared schema, such as :fields_by_number, are
runtime indexes; plugins must not write to them, and should not read plugin
data from them.
The value under a plugin's key is the plugin's own business, but it must be
plain data that Macro.escape/1 accepts (structs, maps, compiled regexes),
because use PB.Schema embeds the compiled schema in a module.
Schema module functions
A plugin may also implement schema_functions/1, returning code that
use PB.Schema injects into every schema module listing the plugin. The code
can call __pb_schema__/0 for the module's compiled schema.
Summary
Callbacks
Adds the plugin's data to a prepared schema.
Returns quoted code to inject into a use PB.Schema module that lists this
plugin, given the plugin's options.
Types
Callbacks
Adds the plugin's data to a prepared schema.
opts are the options given with the plugin's entry, [] for a bare module.
Raise to reject the schema or the options.
Returns quoted code to inject into a use PB.Schema module that lists this
plugin, given the plugin's options.