Create a plugin for Google Protocol BufferDaniele Esposti's Blog, in 13 September 2015
Google’s Protocol Buffer is a library to encode and decode messages in a binary format optimised for compactness and portability between different platforms. At the moment the core library can generate code for C/C++, Java and Python but additional languages can be implemented by writing a plugin for the Protobuf’s compiler.
There is already a list of plugins to support third party languages however you can write your how plugin to output custom code tailored for your needs. In this post I’m going show an example of a plugin written in Python.
Before start writing the plugin we need to install the Protocol Buffer compiler:
to be able to compile ore
.proto file through our plugin and the Python Protobuf package:
to implement the plugin.
Writing the plugin
The interface between the
protoc compiler is pretty simple: the compiler will pass a
CodeGeneratorRequest message on the
stdin and your plugin will output the generated code in a
CodeGeneratorResponse on the
stdout. So the first step is to write the code which reads the request and write an empty response:
protoc compiler follows a naming convention for the name of the plugins, as state [protobuf-plugin][here] you can save the code above in a file called
protoc-gen-custom in your
PATH or save it with any name you prefer (like
my-plugin.py) and pass the plugin’s name and path to the
--plugin command line option.
We are choosing the second option so we’ll save our plugin as
my-plugin.py, then compiler’s invocation will looks like this (assuming that the
build directory already exists):
The content of
hello.proto file is simply this:
The command above will not generate any output because our plugin does nothing, time now to write some meaningful output.
Lets modify the
generate_code() function to generate a JSON representation of the
.proto file but first we need a function to traverse the AST and return all the enumerator, messages and nested types:
And now the new
.proto file in the request we iterate over all the items (enumerators, messages and nested types) and we write some informations in a dictionary. Then we add a new file to the response and we set the filename, in this case equal to the original filename plus the
.json extension, and the content which is the JSON representation of the dictionary.
If you run again the protobuf compiler it will output a file named
hello.proto.json in the
build directory with this content:
In this post we walked through the creation of a Protocol Buffer plugin to compile a
.proto file into simplified representation in JSON format. The core part is the interface code to read a request from the
stdin, traverse the AST and write the response on the
However you are not limited in just transforming the input into another format but you can use the request to output any code in any language, you can parse a
.proto file and output code for a RESTful API in Node.js, converting the message and enum definitions into a XML file or even generate another
.proto file i. e. without the deprecated fields.