Options
Plugins can declare typed options that users pass via buf.gen.yaml, giving them a structured way to configure code generation behavior.
Plugin options
Define plugin options as a dataclass and pass it as the third argument to run():
from dataclasses import dataclass
from protobuf.plugin import Schema, run
@dataclass
class Options:
verbose: bool = False
def generate(schema: Schema[Options]) -> None:
if schema.options.verbose:
...
run("protoc-gen-hello", "0.1.0", Options, generate)
Pass options in buf.gen.yaml as a comma-separated opt: value:
Supported field types: str, bool, int, float, Literal[...], StrEnum, IntEnum, list[T], dict[str, T].
| None can be added for optional options.
Framework-reserved options
The framework reserves certain option names for all plugins, currently: no_fmt_off.
If your Options dataclass defines a field with a reserved name, run() raises a ValueError.
no_fmt_off
When set, omits the # fmt: off line from the generated file preamble.
Use this when you want ruff to format the generated output:
Example: Sensitive fields plugin
Here is a plugin that generates a _sensitive.py file for each proto file, listing all fields marked with the sensitive custom option from extensions:
#!/usr/bin/env python3
from protobuf.plugin import Schema, run
from gen.options_pb import ext_sensitive
def generate(schema: Schema) -> None:
for desc in schema.files_to_generate:
f = schema.generate_file(desc, "_sensitive.py")
f.preamble(desc)
f.print()
sensitive_fields = [
(msg, field)
for msg in desc.messages
for field in msg.fields
if field.proto.options is not None and field.proto.options[ext_sensitive]
]
with f.scope("SENSITIVE_FIELDS: list[tuple[str, str]] = ["):
for msg, field in sensitive_fields:
f.print(f'("{msg.name}", "{field.name}"),')
f.print("]")
run("protoc-gen-sensitive", "0.1.0", generate)