Created
November 5, 2015 04:25
-
-
Save johnllao/5ffbe24a021891e7d887 to your computer and use it in GitHub Desktop.
Protobuf Descriptor and Dynamic Messages
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.hello.protobuf; | |
import java.util.Map; | |
import com.google.protobuf.*; | |
import com.google.protobuf.Descriptors.*; | |
import com.google.protobuf.DescriptorProtos.*; | |
public class HelloProto { | |
public static void main(String[] args) throws Exception { | |
final String descFile = "proto/proto.desc"; | |
final String proto = "Model.proto"; | |
final String messageTypeName = "Member"; | |
Map<String, FileDescriptorProto> fileDescProtos = ProtoUtil.getFileDescriptorProtos(descFile); | |
FileDescriptorProto fileDescProto = fileDescProtos.get(proto); | |
FileDescriptor[] dependencies = ProtoUtil.getDependencies(fileDescProtos, fileDescProto); | |
FileDescriptor fileDesc = FileDescriptor.buildFrom(fileDescProto, dependencies); | |
Descriptor desc = fileDesc.findMessageTypeByName(messageTypeName); | |
displayFieldDetails(desc.findFieldByName("id")); | |
displayFieldDetails(desc.findFieldByName("name")); | |
displayFieldDetails(desc.findFieldByName("address")); | |
displayFieldDetails(desc.findFieldByName("country")); | |
displayFieldDetails(desc.findFieldByName("city")); | |
displayFieldDetails(desc.findFieldByName("gender")); | |
System.out.println(); | |
DynamicMessage dynMessage = DynamicMessage.newBuilder(desc) | |
.setField(desc.findFieldByName("id"), 1) | |
.setField(desc.findFieldByName("name"), "John Lao") | |
.setField(desc.findFieldByName("address"), "Block 1 Happy St.") | |
.setField(desc.findFieldByName("country"), createCountryCity(desc.findFieldByName("country").getMessageType())) | |
.setField(desc.findFieldByName("city"), createCountryCity(desc.findFieldByName("city").getMessageType())) | |
.setField(desc.findFieldByName("gender"), desc.findFieldByName("gender").getEnumType().findValueByName("MALE")) | |
.build(); | |
byte[] dynMessageInBytes = dynMessage.toByteArray(); | |
DynamicMessage dynMessage2 = DynamicMessage.parseFrom(desc, dynMessageInBytes); | |
System.out.println(dynMessage2); | |
} | |
private static DynamicMessage createCountryCity(Descriptor desc) { | |
DynamicMessage dynMessage = DynamicMessage.newBuilder(desc) | |
.setField(desc.findFieldByName("code"), "SG") | |
.setField(desc.findFieldByName("name"), "Singapore") | |
.build(); | |
return dynMessage; | |
} | |
private static void displayFieldDetails(FieldDescriptor fieldDesc) { | |
System.out.printf("%s : %s", | |
fieldDesc.getName(), | |
fieldDesc.getJavaType().name()); | |
if (fieldDesc.getJavaType().name().equals("MESSAGE")) { | |
System.out.printf(" (%s)", fieldDesc.getMessageType().getName()); | |
} | |
else if (fieldDesc.getJavaType().name().equals("ENUM")) { | |
System.out.printf(" (%s)", fieldDesc.getEnumType().getName()); | |
} | |
System.out.println(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.hello.proto; | |
import "Static.proto"; | |
message Member { | |
required int32 id = 1; | |
required string name = 2; | |
required string address = 3; | |
required Country country = 4; | |
required City city = 5; | |
required Gender gender = 6; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off | |
erase /F /Q proto\proto.desc | |
protoc.exe --include_imports --proto_path=proto --descriptor_set_out=proto/proto.desc proto/* | |
@echo on |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.hello.protobuf; | |
import java.io.InputStream; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import com.google.protobuf.*; | |
import com.google.protobuf.DescriptorProtos.*; | |
import com.google.protobuf.Descriptors.*; | |
public class ProtoUtil { | |
public static FileDescriptorSet getFileDescriptorSet(String descFilePath) throws Exception { | |
InputStream inStream = HelloProto.class.getClassLoader().getResourceAsStream(descFilePath); | |
FileDescriptorSet fileDescSet = FileDescriptorSet.parseFrom(inStream); | |
return fileDescSet; | |
} | |
public static Map<String, FileDescriptorProto> getFileDescriptorProtos(String descFilePath) throws Exception { | |
FileDescriptorSet fileDescSet = getFileDescriptorSet(descFilePath); | |
return getFileDescriptorProtos(fileDescSet); | |
} | |
public static Map<String, FileDescriptorProto> getFileDescriptorProtos(FileDescriptorSet fileDescSet) { | |
Map<String, FileDescriptorProto> map = new HashMap<String, FileDescriptorProto>(); | |
List<FileDescriptorProto> fileDescProtos = fileDescSet.getFileList(); | |
for (FileDescriptorProto fileDescProto : fileDescProtos) { | |
map.put(fileDescProto.getName(), fileDescProto); | |
} | |
return map; | |
} | |
public static FileDescriptor[] getDependencies(Map<String, FileDescriptorProto> fileDescProtos, FileDescriptorProto fileDescProto) throws Exception { | |
if (fileDescProto.getDependencyCount() == 0) | |
return new FileDescriptor[0]; | |
ProtocolStringList dependencyList = fileDescProto.getDependencyList(); | |
String[] dependencyArray = dependencyList.toArray(new String[0]); | |
int noOfDependencies = dependencyList.size(); | |
FileDescriptor[] dependencies = new FileDescriptor[noOfDependencies]; | |
for (int i = 0; i < noOfDependencies; i++) { | |
FileDescriptorProto dependencyFileDescProto = fileDescProtos.get(dependencyArray[i]); | |
FileDescriptor dependencyFileDesc = FileDescriptor.buildFrom(dependencyFileDescProto, getDependencies(fileDescProtos, dependencyFileDescProto)); | |
dependencies[i] = dependencyFileDesc; | |
} | |
return dependencies; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.hello.proto; | |
message Country { | |
required string code = 1; | |
required string name = 2; | |
} | |
message City { | |
required string code = 1; | |
required string name = 2; | |
} | |
enum Gender { | |
MALE = 0; | |
FEMALE = 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment