编译protobuf以使用原始类而不是众所周知的类型

时间:2018-01-04 08:45:35

标签: java protocol-buffers protoc proto3

假设我有test.proto文件:

syntax = "proto3";

option java_package = "testing";
option java_outer_classname = "Test_v1";

import "google/protobuf/wrappers.proto";

message TestMessage {
    .google.protobuf.Int32Value integerField = 1;
}

如果我编译(使用protoc v3.5.0)它到c#代码我会得到可以为空的类型属性:

public int? IntegerField {
   get { return integerField_; }
   set { integerField_ = value; }
 }

但是,如果我将其编译为Java代码,则字段将是众所周知的类型:

public Builder setIntegerField(com.google.protobuf.Int32Value value) {
  if (integerFieldBuilder_ == null) {
    if (value == null) {
      throw new NullPointerException();
    }
    integerField_ = value;
    onChanged();
  } else {
    integerFieldBuilder_.setMessage(value);
 }

我正在将项目从proto2移动到proto3,所以我想避免使用众所周知的类型,因为它需要大量工作才能更改相关代码。使用c#项目,我不需要修改任何东西,但在Java中我将需要执行以下示例:

TestMessage.Builder builder = TestMessage.newBuilder();
builder.setIntegerField(5); //<-- instead of this with proto2
builder.setIntegerField(Int32Value.newBuilder().setValue(5)); //<-- I will need to do something like this with proto3

有没有办法将proto文件编译为Java,因此setter会接受基本类/包装器(String,Integer等)作为参数?

1 个答案:

答案 0 :(得分:1)

这里的问题是当缺少值时该怎么做。这不是int32(在.proto中)的问题,因为(在proto3中,至少)int32将始终存在(默认为0)。但是,.google.protobuf.Int32Value消息,因此可能缺少 代表一个值(可能是0)。在C#中,这个概念可以通过int?(可以是null)整齐地表示,但Java没有类似于Nullable<T>的概念。 Int32Value封装了此内容,允许null引用。

如此短的版本:不,和(^^^)这就是原因。

我认为你实际上正在替换以前的东西:

message TestMessage {
    optional int32 integerField = 1;
}

???