是否可以检查原型文件中的枚举值?

时间:2019-06-05 13:27:29

标签: java enums grpc grpc-java proto3

我想验证生成的Java代码中的枚举值。我有以下原始文件:

syntax = "proto3";

import "google/protobuf/empty.proto";

option java_multiple_files = true;
option java_package = "com.package";

package helloworld;

service SomeService {
    rpc DoAction (Request) returns (google.protobuf.Empty) { }
}

enum Currency {
    EUR = 0;
    GBP = 1;
    USD = 2;
}

message Request {
    string id = 1;
    Currency currency = 2;
}

我想在protobuf生成的代码中对Currency枚举进行一些验证,如果值不适用于所提供的枚举(例如:invalid currency),则会丢弃错误消息。有可能吗?

1 个答案:

答案 0 :(得分:0)

您可以验证它,但您也应该了解Protobuf枚举的细微差别。

  1. 始终为每个枚举包含一个UNKNOWN = 0;枚举值。当Protobuf不知道枚举值对应于什么时,它将其设置为默认值。这样,您就可以检测到带有新代码的新客户端何时使用服务器无法理解的值。另外,如果未设置该字段,则自然等于UNKNOWN,让您检查该字段是否不存在。 (如果您确实希望允许缺少的枚举,请将它们包装在message{}中。)

  2. 在服务器应用程序处理程序中,应检查客户端提供的支持的值之一。如果不是其中之一,则应使用INVALID_ARGUMENT状态代码使RPC失败:

    out: {
      switch (req.getCurrency()) {
        case EUR: 
        case GBP:
        case USD: break out;
        case UNKNOWN:
          responseObserver.onError(
              Status.INVALID_ARGUMENT
                  .withDescription("bad currency " + req.getCurrency())
                  .asRuntimeException());
          return;
      }
      throw new AssertionError("missed case!");
    }
    // keep handling the request

此代码检查该代码是否为受支持的代码之一。如果输入了不受支持的代码,它将以UNKNOWN的情况处理,并提早返回错误。如果您修改了原型并添加了更多案例,则静态分析将捕获丢失的案例(或引发AssertionError)。请注意,如果客户端更新其原型,则不会发生。避免使用default大小写,因为修改原型时很容易错过它。或者,您可以将所有支持的案例放在地图中,然后检查是否存在。