I have a proto definition with nested classes
syntax = "proto3"; option java_package = "com.spot.proto.v1.config"; package v1config; // ClusterConfig proto is used to maintain the params required by all the services at a central place. message ClusterConfig { enum LogLevel { UNKNOWN_TYPE = 0; DEBUG = 1; INFO = 2; WARN = 3; ERROR = 4; FATAL = 5; } message Network { string ip = 1; int32 port = 2; } message Constants { message SlackNotifier { message Channel { string name = 1; } string auth_token = 1; map<string, Channel> channels = 2; bool is_enabled = 3; } message Kafka { string broker_list = 1; } Kafka kafka = 2; } message Support { Network network = 1; } Support support = 1; ... }
When I generate the java classes with option java_multiple_files = false;
it creates a single java class, ClusterConfigOuterClass.java
with all the Java classes/enums/etc generated for the top-level messages, services, and enumerations nested inside it. This is expected.
But if I use option java_multiple_files = true;
then I am seeing it is generating two additional classes ClusterConfig.java
, ClusterConfigOrBuilder.java
along with ClusterConfigOuterClass.java
. ClusteConfig.java
now contains the nested classes.
The documentation states like below:-
java_multiple_files (file option): If false, only a single .java file will be generated for this .proto file, and all the Java classes/enums/etc. generated for the top-level messages, services, and enumerations will be nested inside of an outer class (see java_outer_classname). If true, separate .java files will be generated for each of the Java classes/enums/etc. generated for the top-level messages, services, and enumerations, and the wrapper Java class generated for this .proto file won’t contain any nested classes/enums/etc. This is a Boolean option that defaults to false. If not generating Java code, this option has no effect.
So should not each nested message like Kafka
, Network
, etc go into a separate java file?
- Java 11
- Protoc – 3.10
Advertisement
Answer
With only Nested classes, the java_multiple_files
will not do anything, and this is on purpose. You are explicitly giving a context for Kafka
, Network
, etc… They are relevant only in their parent object.
Now, if you really wanted to generate multiple files, you would have to do something like:
enum LogLevel { UNKNOWN_TYPE = 0; DEBUG = 1; INFO = 2; WARN = 3; ERROR = 4; FATAL = 5; } message Channel { string name = 1; } message SlackNotifier { string auth_token = 1; map<string, Channel> channels = 2; bool is_enabled = 3; } message Kafka { string broker_list = 1; } message Constants { Kafka kafka = 2; } message Network { string ip = 1; int32 port = 2; } message Support { Network network = 1; } message ClusterConfig { Support support = 1; //... }
Then, to go further, if you wanted to give them a Context in which these objects should be used (maybe because you have team, and you don’t want other developers to misuse these objects), you could put them in a package like:
package mycompany.service.cluster
and then to use your Kafka
object for example, they will need to give the fully qualified type (except if they are in the same package):
mycompany.service.cluster.Kafka