Protocol Buffers — Custom Codegen
I went through quite a bit of struggle to decode how to add custom plugin to protoc. In this article, I will introduce protocol buffer’s insertion points — which is hidden deep in the documentation, and how these are the key to write custom code generation for protos.
The “Why”
Only primitives are supported in protocol buffers. protoc
can compile a string
type in protocol buffer to java.lang.String
and also to python String. But if you were to add support for, say, LocalDate, protoc should be able to represent this type in all the supported language. Customizing protoc codegen opens the door to represent a proto message in whatever type you want, in the language you want.
The “How”
Via insertion points. This is how the auto generated proto class looks like.
These are the insertion points we have. The insertion points are self-explanatory if you follow with the example above.
- interface_extends
- message_implements
- builder_implements
- builder_scope
- class_scope
- outer_class_scope
This insertion point is how we are able to add custom code to the already generated code. Say I want to add a static method to the above outerClass that just prints default greeting. I just need to add this method to the outerClassScope insertion point.
customCode = "
public static String defaultGreeting() {
return “Hello”;
}"outerClassScope = "// @@protoc_insertion_point(outer_class_scope)"code.replace(outerClassScope, customCode+outerClassScope)
To know more about the applications of such custom code in protoc’s generated code, and how to do that, check out my project at github — README has enough details on the custom plugin along with gradle integration.
References
- https://stackoverflow.com/questions/50806894/how-can-i-add-my-own-code-to-java-generated-classes-from-proto-file/58044855#58044855
- https://expobrain.net/2015/09/13/create-a-plugin-for-google-protocol-buffer/
- Custom annotations : https://giorgio.azzinna.ro/2017/07/extending-protobuf-custom-options/
- Protobuf-Gradle-plugin : https://github.com/google/protobuf-gradle-plugin