:author: rules_proto_grpc :description: Custom plugin support for protoc and Bazel proto_library targets :keywords: Bazel, Protobuf, gRPC, Protocol Buffers, Rules, Build, Starlark, Plugin, Protoc .. _sec_custom_plugins: Custom Plugins ============== Custom plugins are supported by ``rules_proto_grpc``, through the use of the ``proto_plugin`` Starlark rule to create a plugin target in a ``BUILD`` file and by then creating a rule that uses ``proto_compile_impl`` with the new plugin. To add a new plugin, you can generally follow the pattern seen in the multiple language examples in this repository; simpler languages such as C++ are generally more understandable as examples. In short, the basic idea is: 1. In a ``BUILD`` file, load the ``proto_plugin`` rule with ``load("@rules_proto_grpc//:defs.bzl", "proto_plugin")`` and use this to define all of the behaviour of your particular protoc plugin using the available attrs (listed in full below). The minimum required specification for a plugin needs a ``name``, ``tool`` and one of ``outputs``, ``out`` or ``output_directory``. The ``tool`` attr is a label that refers to the binary target for the plugin itself and can be ``select()``'ed based on your platform. The choice of output type depends on the sort of files your plugin generates (pick one!): - ``outputs``: Provide a list of strings patterns that predicts the pattern of files generated by the plugin. Use this type for plugins that produce one output file per input proto file, such as Python producing a ``.py`` file. - ``out``: The name of a single output file generated by the plugin. Use this type for plugins that produce a single output file per call to protoc, such as Java producing a ``.jar`` file. - ``output_directory``: Set to true if your plugin generates files in a non-predictable way, for example if the output paths depend on the service names within the files. .. code-block:: python load("@rules_proto_grpc//:defs.bzl", "proto_plugin") proto_plugin( name = "example_plugin", outputs = ["{protopath}_example.py"], # {protopath} gets replaced with relative path to each .proto file tool = "//label/of/plugin:binary", # Point this at your plugin binary target, use select if desired ) 2. In a ``.bzl`` file, create a compilation rule using the below template, substituting the plugin target label created above where indicated. The ``proto_compile_attrs`` contains a set of attrs that the ``proto_compile_impl`` rule implementation expects. .. code-block:: python load("@rules_proto//proto:defs.bzl", "ProtoInfo") load( "@rules_proto_grpc//:defs.bzl", "ProtoPluginInfo", "proto_compile_attrs", "proto_compile_impl", "proto_compile_toolchains", ) # Create compile rule example_compile = rule( implementation = proto_compile_impl, attrs = dict( proto_compile_attrs, _plugins = attr.label_list( providers = [ProtoPluginInfo], default = [ Label("//