Protobuf

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

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License