http://blog.csdn.net/xiao__gui/article/details/37874081
https://cxwangyi.wordpress.com/2012/04/13/mastering-google-protocol-buffer-custom-option-with-repeated-fields/
https://binkley.blogspot.com/2012/01/defaulting-message-fields-in-protobuf.html
http://stackoverflow.com/questions/18836727/protocol-buffer-objects-generated-at-runtime
http://planet.jboss.org/post/generic_marshalling_with_google_protocol_buffers
http://lishihu.com/protobuf/2013/04/30/dynamic-protocol-buffer-message
http://www.udpwork.com/item/8132.html
http://blog.arganzheng.me/posts/reflection-of-protobuf.html
http://www.transylvania-jug.org/archives/365
package tutorial;
option java_package = "com.example.protoctest";
option java_outer_classname = "MetadataProtos";
message Metadata {
required bytes field_descriptor = 1;
optional int32 field_descriptor_idx = 2;
repeated Metadata dependencies = 3;
}
package tutorial;
option java_package = "com.example.protoctest";
option java_outer_classname = "AddressBookProtos";
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}
repeated PhoneNumber phone = 4;
}
message AddressBook {
repeated Person person = 1;
}
package com.example.protoctest;
import java.util.ArrayList;
import org.junit.*;
import static org.junit.Assert.*;
import com.example.protoctest.AddressBookProtos.Person.PhoneType;
import com.example.protoctest.MetadataProtos.Metadata;
import com.google.protobuf.DescriptorProtos.FileDescriptorProto;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FileDescriptor;
import com.google.protobuf.ByteString;
import com.google.protobuf.DynamicMessage;
import com.google.protobuf.Message;
public final class ArbitraryProtoMessageTest {
@Test
public void testArbitraryProtoMessage() throws Exception {
Message msg = getMessage();
Metadata metadata = serializeMetadata(msg);
byte[] msgByte = msg.toByteArray();
metadata = Metadata.newBuilder()
.mergeFrom( metadata.toByteArray() ).build();
FileDescriptor fd = deserializeMetadata(metadata);
DynamicMessage dmsg = DynamicMessage.parseFrom(
fd.getMessageTypes().get(metadata.getFieldDescriptorIdx()),
msgByte);
assertTrue(dmsg.toString().contains("263-1655-2187"));
}
Metadata serializeMetadata(Message msg) {
FileDescriptor fd = msg.getDescriptorForType().getFile();
String msgTypeName = msg.getDescriptorForType().getFullName();
int idx = 0;
for (Descriptor desc : fd.getMessageTypes()) {
if (desc.getFullName().equals( msgTypeName )) { break; }
++idx;
}
assert idx < fd.getMessageTypes().size();
return serialize(fd, idx);
}
Metadata serialize(FileDescriptor fd, int fdIndex) {
Metadata.Builder result = Metadata.newBuilder();
for (FileDescriptor dependency : fd.getDependencies()) {
result.addDependencies(serialize(dependency, -1));
}
result.setFieldDescriptor( ByteString.copyFrom( fd.toProto().toByteArray() ) );
if (fdIndex >= 0) { result.setFieldDescriptorIdx(fdIndex); }
return result.build();
}
FileDescriptor deserializeMetadata(Metadata s) throws Exception {
ArrayList<FileDescriptor> deps = new ArrayList<FileDescriptor>();
for (Metadata m : s.getDependenciesList()) {
deps.add( deserializeMetadata(m) );
}
FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder()
.mergeFrom(s.getFieldDescriptor()).build();
FileDescriptor fileDescriptor = FileDescriptor.buildFrom(fileDescriptorProto,
deps.toArray(new FileDescriptor[deps.size()]));
return fileDescriptor;
}
private Message getMessage() {
return AddressBookProtos.AddressBook.newBuilder().addPerson(
AddressBookProtos.Person.newBuilder()
.setId(42)
.setName("Foo")
.setEmail("test@example.com")
.addPhone(AddressBookProtos.Person.PhoneNumber.newBuilder()
.setNumber("263-1655-2187")
.setType(PhoneType.HOME)
)
).build();
}
}
http://lishihu.com/protobuf/2013/04/30/dynamic-protocol-buffer-message
https://gist.github.com/nandub/950285
http://planet.jboss.org/post/generic_marshalling_with_google_protocol_buffers
https://github.com/os72/protobuf-dynamic
https://cxwangyi.wordpress.com/2010/06/29/google-protocol-buffers-online-parsing-of-proto-file-and-related-data-files/
https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_Data_Grid/6.3/html/Infinispan_Query_Guide/sect-Protobuf_Encoding.html