Skip to content

Instantly share code, notes, and snippets.

@nandub
Created May 1, 2011 05:52
Show Gist options
  • Star 28 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save nandub/950285 to your computer and use it in GitHub Desktop.
Save nandub/950285 to your computer and use it in GitHub Desktop.
ProtobufEnvelope - allows creating a protobuf message without the .proto file dynamically.
import com.google.protobuf.DescriptorProtos;
import com.google.protobuf.Descriptors;
import com.google.protobuf.DynamicMessage;
import com.google.protobuf.Message;
import java.util.HashMap;
/**
* ProtobufEnvelope - allows creating a protobuf message without the .proto file dynamically.
*
* @author Florian Leibert
*/
public class ProtobufEnvelope {
private HashMap<String, Object> values = new HashMap();
private DescriptorProtos.DescriptorProto.Builder desBuilder;
private int i = 1;
public ProtobufEnvelope() {
desBuilder = DescriptorProtos.DescriptorProto.newBuilder();
i = 1;
}
public <T> void addField(String fieldName, T fieldValue, DescriptorProtos.FieldDescriptorProto.Type type) {
DescriptorProtos.FieldDescriptorProto.Builder fd1Builder = DescriptorProtos.FieldDescriptorProto.newBuilder()
.setName(fieldName).setNumber(i++).setType(type);
desBuilder.addField(fd1Builder.build());
values.put(fieldName, fieldValue);
}
public Message constructMessage(String messageName)
throws Descriptors.DescriptorValidationException {
desBuilder.setName(messageName);
DescriptorProtos.DescriptorProto dsc = desBuilder.build();
DescriptorProtos.FileDescriptorProto fileDescP = DescriptorProtos.FileDescriptorProto.newBuilder()
.addMessageType(dsc).build();
Descriptors.FileDescriptor[] fileDescs = new Descriptors.FileDescriptor[0];
Descriptors.FileDescriptor dynamicDescriptor = Descriptors.FileDescriptor.buildFrom(fileDescP, fileDescs);
Descriptors.Descriptor msgDescriptor = dynamicDescriptor.findMessageTypeByName(messageName);
DynamicMessage.Builder dmBuilder =
DynamicMessage.newBuilder(msgDescriptor);
for (String name : values.keySet()) {
dmBuilder.setField(msgDescriptor.findFieldByName(name), values.get(name));
}
return dmBuilder.build();
}
public void clear() {
desBuilder = DescriptorProtos.DescriptorProto.newBuilder();
i = 1;
values.clear();
}
public static void main(String[] args) throws Exception {
ProtobufEnvelope pe = new ProtobufEnvelope();
int i = 1;
for (; i < 5; i++) {
pe.<String>addField("Field" + i, i * 1000 + "FOO", DescriptorProtos.FieldDescriptorProto.Type.TYPE_STRING);
}
for (; i < 10; i++) {
pe.<Integer>addField("Field" + i, i * 1000, DescriptorProtos.FieldDescriptorProto.Type.TYPE_INT32);
}
Message m = pe.constructMessage("TestMessage");
System.out.println(m);
}
}
@noclayto
Copy link

👍

@zagorulkinde
Copy link

very useful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment