我必须使用一个已发布的(第三方)协议缓冲区(.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)
}
这里有一个小例子。
使用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.