当前位置: 首页 > 知识库问答 >
问题:

如何重命名生成的Java类中的字段以防止Java编译器出现问题

穆铭晨
2023-03-14

我必须使用一个已发布的(第三方)协议缓冲区(.proto)文件,其中包含Java保留关键字列表中名称为的字段。所以我不能更改这个文件的名称。因此,在将(通过protoc)协议缓冲区编译成Java代码后,我得到了一个不能用Java编译的类。

例如,我必须解析的消息是在C的帮助下使用原始字段的名称(在Java中无效)生成的。

据我所知,在使用此消息/类的过程中,如果没有问题,我无法更改生成的代码。

如何在生成的Java类中安全地更改生成字段的名称(在运行protoc期间使用一些映射规则或使用注释)?

样本。

原型文件:

package sample.wrongname.protobuf;

enum SomeType {
    cool_name = 1;
    another_cool_name = 2;
    native = 3;
}

生成的Java类:

public final class Sample {
  private Sample() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
  }
  /**
   * Protobuf enum {@code sample.wrongname.protobuf.SomeType}
   */
  public enum SomeType
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <code>cool_name = 1;</code>
     */
    cool_name(0, 1),
    /**
     * <code>another_cool_name = 2;</code>
     */
    another_cool_name(1, 2),
    /**
     * <code>native = 3;</code>
     */
    native(2, 3),
    ;

    /**
     * <code>cool_name = 1;</code>
     */
    public static final int cool_name_VALUE = 1;
    /**
     * <code>another_cool_name = 2;</code>
     */
    public static final int another_cool_name_VALUE = 2;
    /**
     * <code>native = 3;</code>
     */
    public static final int native_VALUE = 3;


    public final int getNumber() { return value; }

    public static SomeType valueOf(int value) {
      switch (value) {
        case 1: return cool_name;
        case 2: return another_cool_name;
        case 3: return native;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<SomeType>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static com.google.protobuf.Internal.EnumLiteMap<SomeType>
        internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<SomeType>() {
            public SomeType findValueByNumber(int number) {
              return SomeType.valueOf(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(index);
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return Sample.getDescriptor().getEnumTypes().get(0);
    }

    private static final SomeType[] VALUES = values();

    public static SomeType valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int index;
    private final int value;

    private SomeType(int index, int value) {
      this.index = index;
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:sample.wrongname.protobuf.SomeType)
  }


  public static com.google.protobuf.Descriptors.FileDescriptor
      getDescriptor() {
    return descriptor;
  }
  private static com.google.protobuf.Descriptors.FileDescriptor
      descriptor;
  static {
    java.lang.String[] descriptorData = {
      "\n\014sample.proto\022\031sample.wrongname.protobu" +
      "f*<\n\010SomeType\022\r\n\tcool_name\020\001\022\025\n\021another_" +
      "cool_name\020\002\022\n\n\006native\020\003"
    };
    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
          public com.google.protobuf.ExtensionRegistry assignDescriptors(
              com.google.protobuf.Descriptors.FileDescriptor root) {
            descriptor = root;
            return null;
          }
        };
    com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
        }, assigner);
  }

  // @@protoc_insertion_point(outer_class_scope)
}

共有1个答案

怀飞扬
2023-03-14

这里有一个小例子。

使用Java保留关键字的Protobuffer。

package wrong.name;
option java_outer_classname = "WrongProtos";
message Foo {
    required SomeType id = 1;
}
enum SomeType {
    cool_name = 1;
    another_cool_name = 2;
    native = 3;
}

Protobuffer使用相同的结构,但名称不同。

package right.name;
option java_outer_classname = "RightProtos";
message Foo {
    required SomeType id = 1;
}
enum SomeType {
    cool_name = 1;
    another_cool_name = 2;
    different = 3;
}

编译protobuffer

protoc --java_out=src/ *.proto

重命名在WrongProtos.java

native(2, 3)  -->  nativeFoo(2, 3)
case 3: return native;  -->  case 3: return nativeFoo;

一个小片段,表明可以使用两个protobuff定义读取该结构。

WrongProtos.Foo.Builder outFoo = WrongProtos.Foo.newBuilder();
outFoo.setId(WrongProtos.SomeType.nativeFoo);
try (FileOutputStream output = new FileOutputStream("/tmp/proto.bin")) {
    outFoo.build().writeTo(output);
}
System.out.printf("outFoo number: %d  name: %s%n",
        outFoo.getId().getNumber(), outFoo.getId());

RightProtos.Foo inFoo = RightProtos.Foo.parseFrom(
        new FileInputStream("/tmp/proto.bin"));
System.out.printf("inFoo number: %d  name: %s%n",
        inFoo.getId().getNumber(), inFoo.getId());
}

输出

outFoo number: 3  name: nativeFoo
inFoo number: 3  name: different

输出显示,只有在访问字段名本身的情况下,才会有差异。二进制数据中不存储字段名。

编辑另一种方法是将字段重命名为大写--

 类似资料:
  • 有没有图书馆可以为我做这件事?例如,如果我重命名一个方法,我也需要重命名它的所有用例。 这不仅适用于方法,还适用于所有被重命名的东西(字段、参数...)

  • 我目前正在使用JAXB使用Mojo Maven插件'jaxb2-maven-plugin'生成的类为我们的Netbeans平台应用程序实现功能。不幸的是,XSD文件的创建不在我手中,它们是机密的。我试图提供一个最小的运行示例来进一步证明这一点,但现在我希望有人可以仅从我的描述中将我推向正确的方向。 我们有很多XSD文件,在过去的几周里得到了一些补充。其中两个XSD(我们称之为A.xsd和B.xsd

  • 问题内容: 我已经使用了Java编译器树api来为Java源文件生成ast。但是,我无法访问源文件中的注释。 到目前为止,我一直找不到从源文件中提取注释的方法..是否有使用编译器API或其他工具的方法? 问题答案: 通过使用getsourceposition()和一些字符串操作来解决问题(不需要正则表达式)

  • 问题内容: 在此处输入图片说明我一直在从事个人项目,以使编程更好。我的目标是使其更加强大,我才刚刚开始。我目前是计算机 科学专业的学生。无论如何,我正在如图所示制作程序的一部分。我计算小时工资,并提供一些尚未执行的输出。我正在使用DocumentListener,它将自动进行计算。将文本从框中完全删除时出现错误,我尝试使用if语句修复它: 这是我到目前为止所拥有的。还没有完成,对于新手代码,我深表

  • 这是我目前所掌握的。它还没有完成,我为noob代码道歉。我从两个月前开始实际编码。 }

  • 我试图从protobuf生成java类。 下面是我的协议- 我运行命令main/exec/protoc--java\u out=main/java main/proto/datamodel。协议 该协议是从链接https://github.com/protocolbuffers/protobuf/releases/tag/v3.7.1下载的,osx-x86_64.zip.我也尝试了3.8.0和3.