Skip to content
Advertisement

proto3: Why setting java_multiple_files = true not creating separate java classes for each proto message?

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

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement