Skip to content

mix protobuf.generate #316

@drowzy

Description

@drowzy

For context: elixir-grpc/grpc#274

I'm working on http/json transcoding for grpc and basically want to populate MethodDescriptors options with an extension during compilation.

The recommended approach is to install the escript globaly and use the executable from
protoc it's hard to see a way to provide extensions that needs to be loaded during compilation in order to to populate __pb_extensions__ correctly without creating a new protoc plugin.

Having a complementary mix task that calls protoc using descriptor_set_out would allow compilation to be executed in the context the local project instead of through a global executable. This is the approach taken in protox.

I would think that most projects already contains some script which calls protoc to compile their .proto files. This would remove this indirection and at the same time enable:

  • Extensions in the current project would be picked up automatically by Protobuf.load_extensions() (or could be provided as an argument to protobuf.generate).

  • No potential version difference between protobuf installed in the project and the escript installed globally.

  • Allow easier integration into the codgen. Generators could be modules provided to protobuf instead of require that they are defined in protobuf.

Proposal

mix protobuf.generate \
--include-path=./priv/protos \ 
--include-path=./deps/googleapi \
--output-path=./lib \
--transform-module=MyTransformModule \
--plugins=grpc \
--one-file-per-module=false \
--generate-descriptors=true \
--package_prefix="my_app.protos" \
--include-docs=true \
google/api/http.proto google/api/annotations.proto helloworld.proto

Which generate a protoc call like:

protoc --include_imports \
--include_source_info \
-o /Users/simont/dev/protobuf/_build/dev/protobuf_vxuilqfaejtrogmc \
-I priv/proto \
-I deps/googleapis \
google/api/http.proto google/api/annotations.proto helloworld.proto

This would output a FileDescriptorSet into a temporary file.
Combined with the parameters provided through protobuf.generate it's enough to create a CodeGeneratorRequest and perform the same logic as is done in Protobuf.Protoc.CLI. The resulting CodeGeneratorResponse is used to write files to disk.

What do you think? I you think it sounds reasonable I can send a PR :).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Effort:LargeKind:FeatureA new feature that's not currently in the library.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions