I am building an application that will be given protobuf definition at
runtime. E.g.:
syntax = "proto3";
package testing;
message MessageWithComments {
// Leading field comment.
string foo = 1;
}
I want to be able to create messages of the given protobuf definition at
runtime in my application. This is what I am trying:
First, I run:
protoc --descriptor_set_out ...
Then, I create a DescriptorProto:
FileDescriptorSet descriptorSet = FileDescriptorSet.parseFrom(bytes);
List<FileDescriptorProto> descriptorProtos = descriptorSet.getFileList();
DescriptorProto descriptor = DescriptorProtos.FileDescriptorProto
.parseFrom(descriptorProtos.get(0).toByteArray())
.getMessageType(0);
Then, I am trying to build the message like this: this whole code is
lengthy but what I am doing is:
1. Create a message builder from the DescriptorProto in above step
2. Then iterate over the fields and populate then with values
3. If a field is of type MESSAGE then we have to recursively fill it (go
back to Step 1)
i am copying the code below but it gives me this error:
Exception in thread "main" java.lang.IllegalArgumentException: Wrong object
type used with protocol message reflection.
Field number: 2, field java type: MESSAGE, value type: java.lang.String
at
com.google.protobuf.FieldSet$Builder.verifyType(FieldSet.java:1214)
at com.google.protobuf.FieldSet$Builder.setField(FieldSet.java:1076)
at
com.google.protobuf.DynamicMessage$Builder.setField(DynamicMessage.java:545)
i tried with different protos and its the same error everytime. Can anybody
help me please?
DynamicMessage message = printAllFieldsDp(descriptor);
public static DynamicMessage printAllFieldsDp(DescriptorProto dp) {
Builder builder = DynamicMessage.newBuilder(dp);
for(Map.Entry<FieldDescriptor, Object> entry : builder.getAllFields().
entrySet()) {
FieldDescriptor d = entry.getKey();
String name = d.getFullName();
System.out.println("printing fields of " + name);
Object o = entry.getValue();
if (o != null) {
Object v = printAllFields(o);
builder.setField(d, v);
}
}
return builder.build();
}
private static Object printAllFields(Object o) {
if (o instanceof FieldDescriptorProto) {
FieldDescriptorProto p = (FieldDescriptorProto) o;
System.out.printf("%s %s %s\n", p.getName(), p.getType(), p.getTypeName()); //
Edw_Create_Datetime TYPE_MESSAGE .NBkgsMeasure.Timestamp
switch (p.getType().toString()) {
case "TYPE_STRING":
return "test";
case "TYPE_INT32":
return 10;
case "TYPE_INT64":
return -100;
case "TYPE_FLOAT":
return 3.14156;
case "TYPE_MESSAGE":
return printAllFieldsFdp(p);
default:
throw new RuntimeException("not implemented");
}
}
if (o instanceof FieldDescriptor) {
FieldDescriptor fd = (FieldDescriptor)o;
System.out.printf("%s %s\n", fd.getName(), fd.getType()); //
Summary_Quote_Flg TYPE_STRING
switch (fd.getType().toString()) {
case "TYPE_STRING":
return "test";
case "TYPE_INT32":
return 10;
case "TYPE_INT64":
return -100;
case "TYPE_FLOAT":
return 3.14156;
default:
throw new RuntimeException("not implemented");
}
}
if (o instanceof DescriptorProto) {
return printAllFieldsDp((DescriptorProto)o);
}
if (o instanceof List) {
List l = (List)o;
int n = l.size();
List t = new ArrayList();
for (int i = 0; i < n; i++) {
Object e = l.get(i);
t.add(printAllFields(e));
}
return t;
}
return o;
}
public static DynamicMessage printAllFieldsFdp(FieldDescriptorProto dp) {
Builder builder = DynamicMessage.newBuilder(dp);
for(Map.Entry<FieldDescriptor, Object> entry : builder.getAllFields().
entrySet()) {
FieldDescriptor d = entry.getKey();
String name = d.getFullName();
System.out.println("printing fields of " + name);
Object o = entry.getValue();
if (o != null) {
Object v = printAllFields(o);
builder.setField(d, v);
}
}
return builder.build();
}
--
You received this message because you are subscribed to the Google Groups
"Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/protobuf/66a72ef8-a89f-4cb2-83ad-8c2e32b0d601n%40googlegroups.com.