proto3:为什么设置 java_multiple_files = true 不为每个原型消息创建单独的 java 类?

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

我有一个嵌套 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;
    ...  
  }

当我使用 option java_multiple_files = false; 生成 java classes 时,它会创建一个 java class、ClusterConfigOuterClass.java 以及所有 Java classes/enums/etc 为嵌套在其中的顶级消息、服务和枚举生成。这是预期的。

但是,如果我使用 option java_multiple_files = true;,那么我会看到它会生成两个额外的 classes ClusterConfig.javaClusterConfigOrBuilder.java 以及 ClusterConfigOuterClass.javaClusteConfig.java 现在包含嵌套的 classes.

文档说明如下:-

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.

所以像 KafkaNetwork 等嵌套消息不应该放在单独的 java 文件中吗?

只有嵌套 类,java_multiple_files 不会做任何事情,这是故意的。您明确地为 KafkaNetwork 等提供了上下文...它们仅在其父对象中相关。

现在,如果你真的想生成多个文件,你必须这样做:

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;
  //...
}

然后,更进一步,如果你想给他们一个应该使用这些对象的上下文(可能是因为你有团队,并且你不希望其他开发人员滥用这些对象),你可以把它们在一个包中,如:

package mycompany.service.cluster

然后要使用您的 Kafka 对象,他们将需要提供完全限定的类型(除非他们在同一个包中):

mycompany.service.cluster.Kafka

希望对您有所帮助,如果我能进一步帮助您,请告诉我。