下面列出了com.google.protobuf.Type#com.google.protobuf.DescriptorProtos.DescriptorProto 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private String getMessageJavaType(String packageName, DescriptorProto sourceMessageDesc,
FieldDescriptorProto field) {
String fieldType = CommonUtils.findNotIncludePackageType(field.getTypeName());
Map<String, Pair<DescriptorProto, List<FieldDescriptorProto>>> nestedFieldType =
transform(sourceMessageDesc);
// isMap
if (nestedFieldType.containsKey(fieldType)) {
Pair<DescriptorProto, List<FieldDescriptorProto>> nestedFieldPair =
nestedFieldType.get(fieldType);
if (nestedFieldPair.getRight().size() == 2) {
DescriptorProto mapSourceMessageDesc = nestedFieldPair.getLeft();
List<FieldDescriptorProto> mapFieldList = nestedFieldPair.getRight();
String nestedJavaType =
"java.util.Map<" + findJavaType(packageName, mapSourceMessageDesc, mapFieldList.get(0))
+ "," + findJavaType(packageName, mapSourceMessageDesc, mapFieldList.get(1)) + ">";
return nestedJavaType;
} else {
return null;
}
} else {
return CommonUtils.findPojoTypeFromCache(field.getTypeName(), pojoTypeCache);
}
}
private void printMessage(List<DescriptorProto> messageDescList, String javaPackage,
String outerClassName) {
for (DescriptorProto messageDesc : messageDescList) {
String pojoClassType = messageDesc.getName();
String pojoPackageName = javaPackage + "." + outerClassName;
String fullpojoType = pojoPackageName.toLowerCase() + "." + pojoClassType;
pojoTypes.put(pojoClassType, fullpojoType);
PrintMessageFile messageFile =
new PrintMessageFile(generatePath, pojoPackageName, pojoClassType);
try {
messageFile.setMessageFields(messageDesc.getFieldList());
messageFile.setPojoTypeCache(pojoTypes);
messageFile.setSourceMessageDesc(messageDesc);
} finally {
messageFile.print();
}
}
}
Descriptor(final String fullname) throws DescriptorValidationException {
String name = fullname;
String packageName = "";
int pos = fullname.lastIndexOf('.');
if (pos != -1) {
name = fullname.substring(pos + 1);
packageName = fullname.substring(0, pos);
}
this.index = 0;
this.proto = DescriptorProto.newBuilder().setName(name).addExtensionRange(
DescriptorProto.ExtensionRange.newBuilder().setStart(1)
.setEnd(536870912).build()).build();
this.fullName = fullname;
this.containingType = null;
this.nestedTypes = new Descriptor[0];
this.enumTypes = new EnumDescriptor[0];
this.fields = new FieldDescriptor[0];
this.extensions = new FieldDescriptor[0];
this.oneofs = new OneofDescriptor[0];
// Create a placeholder FileDescriptor to hold this message.
this.file = new FileDescriptor(packageName, this);
}
/** See {@link FileDescriptor#setProto}. */
private void setProto(final DescriptorProto proto) {
this.proto = proto;
for (int i = 0; i < nestedTypes.length; i++) {
nestedTypes[i].setProto(proto.getNestedType(i));
}
for (int i = 0; i < oneofs.length; i++) {
oneofs[i].setProto(proto.getOneofDecl(i));
}
for (int i = 0; i < enumTypes.length; i++) {
enumTypes[i].setProto(proto.getEnumType(i));
}
for (int i = 0; i < fields.length; i++) {
fields[i].setProto(proto.getField(i));
}
for (int i = 0; i < extensions.length; i++) {
extensions[i].setProto(proto.getExtension(i));
}
}
public void decompile(FileDescriptorProto fileDescriptor) throws IOException {
if (fileDescriptor.hasPackage()) {
indentedFormat("package %s;", fileDescriptor.getPackage());
absolutePackage = "." + fileDescriptor.getPackage() + ".";
}
for (String dependency : fileDescriptor.getDependencyList()) {
indentedFormat("import \"%s\";", dependency);
}
if (fileDescriptor.hasOptions()) {
decompileOptions(fileDescriptor.getOptions());
}
decompileMembers(fileDescriptor.getEnumTypeList(),
fileDescriptor.getMessageTypeList(),
Collections.<FieldDescriptorProto>emptyList(),
Collections.<DescriptorProto.ExtensionRange>emptyList(),
fileDescriptor.getExtensionList());
for (ServiceDescriptorProto serviceDescriptor : fileDescriptor.getServiceList()) {
decompile(serviceDescriptor);
}
newline();
flush();
}
@Nullable
private static String getFullName(FileDescriptorProto descriptor, List<Integer> path) {
String fullNameSoFar = descriptor.getPackage();
switch (path.get(0)) {
case FileDescriptorProto.MESSAGE_TYPE_FIELD_NUMBER:
final DescriptorProto message = descriptor.getMessageType(path.get(1));
return appendMessageToFullName(message, path, fullNameSoFar);
case FileDescriptorProto.ENUM_TYPE_FIELD_NUMBER:
final EnumDescriptorProto enumDescriptor = descriptor.getEnumType(path.get(1));
return appendEnumToFullName(enumDescriptor, path, fullNameSoFar);
case FileDescriptorProto.SERVICE_FIELD_NUMBER:
final ServiceDescriptorProto serviceDescriptor = descriptor.getService(path.get(1));
fullNameSoFar = appendNameComponent(fullNameSoFar, serviceDescriptor.getName());
if (path.size() > 2) {
fullNameSoFar = appendFieldComponent(
fullNameSoFar, serviceDescriptor.getMethod(path.get(3)).getName());
}
return fullNameSoFar;
default:
return null;
}
}
@Nullable
private static String appendToFullName(
DescriptorProto messageDescriptor, List<Integer> path, String fullNameSoFar) {
switch (path.get(0)) {
case DescriptorProto.NESTED_TYPE_FIELD_NUMBER:
final DescriptorProto nestedMessage = messageDescriptor.getNestedType(path.get(1));
return appendMessageToFullName(nestedMessage, path, fullNameSoFar);
case DescriptorProto.ENUM_TYPE_FIELD_NUMBER:
final EnumDescriptorProto enumDescriptor = messageDescriptor.getEnumType(path.get(1));
return appendEnumToFullName(enumDescriptor, path, fullNameSoFar);
case DescriptorProto.FIELD_FIELD_NUMBER:
final FieldDescriptorProto fieldDescriptor = messageDescriptor.getField(path.get(1));
return appendFieldComponent(fullNameSoFar, fieldDescriptor.getName());
default:
return null;
}
}
private void addMessageTypes(final List<DescriptorProto> messageTypes,
@Nullable String parentProtoScope,
@Nullable String parentJavaScope,
final Map<String, ClassName> messageTypesMap) {
messageTypes.forEach(t -> {
final String protoTypeName = (parentProtoScope != null ? parentProtoScope : "") + '.' + t.getName();
final String javaClassName = parentJavaScope + '.' + t.getName();
messageTypesMap.put(protoTypeName, ClassName.bestGuess(javaClassName));
addMessageTypes(t.getNestedTypeList(), protoTypeName, javaClassName, messageTypesMap);
});
}
private String findJavaType(String packageName, DescriptorProto sourceMessageDesc,
FieldDescriptorProto field) {
switch (field.getType()) {
case TYPE_ENUM:
return getMessageJavaType(packageName, sourceMessageDesc, field);
case TYPE_MESSAGE:
String javaType = getMessageJavaType(packageName, sourceMessageDesc, field);
return javaType;
case TYPE_GROUP:
logger.info("group have not support yet");
return null;
case TYPE_STRING:
return "String";
case TYPE_INT64:
return "Long";
case TYPE_INT32:
return "Integer";
case TYPE_BOOL:
return "Boolean";
case TYPE_DOUBLE:
return "Double";
case TYPE_FLOAT:
return "Float";
default:
logger.info("have not support this type " + field.getType()
+ ",please contact [email protected] for support");
return null;
}
}
private Map<String, Pair<DescriptorProto, List<FieldDescriptorProto>>> transform(
DescriptorProto sourceMessageDesc) {
Map<String, Pair<DescriptorProto, List<FieldDescriptorProto>>> nestedFieldMap =
Maps.newHashMap();
sourceMessageDesc.getNestedTypeList().forEach(new Consumer<DescriptorProto>() {
@Override
public void accept(DescriptorProto t) {
nestedFieldMap.put(t.getName(),
new ImmutablePair<DescriptorProto, List<FieldDescriptorProto>>(t, t.getFieldList()));
}
});
return nestedFieldMap;
}
private void doPrint(FileDescriptorProto fdp, String javaPackage, String outerClassName) {
List<DescriptorProto> messageDescList = Lists.newArrayList(fdp.getMessageTypeList());
List<ServiceDescriptorProto> serviceDescList = Lists.newArrayList(fdp.getServiceList());
List<EnumDescriptorProto> enumDescList = Lists.newArrayList(fdp.getEnumTypeList());
messageDescList.stream().filter(temp -> temp.getEnumTypeList() != null)
.forEach(temp -> enumDescList.addAll(temp.getEnumTypeList()));
printEnum(enumDescList, javaPackage, outerClassName);
printMessage(messageDescList, javaPackage, outerClassName);
printService(serviceDescList, javaPackage);
}
private void add(DescriptorProto message) {
fullNameSegments.push(message.getName());
pathSegments.push(DescriptorProto.EXTENSION_FIELD_NUMBER);
add(message.getExtensionList());
pathSegments.pop();
pathSegments.push(DescriptorProto.NESTED_TYPE_FIELD_NUMBER);
for (int i = 0; i < message.getNestedTypeCount(); i++) {
pathSegments.push(i);
DescriptorProto nested = message.getNestedType(i);
add(nested);
pathSegments.pop();
}
pathSegments.pop();
fullNameSegments.pop();
}
/**
* Creates additional types (Value, Struct and ListValue) to be added to the Service config.
* TODO (guptasu): Fix this hack. Find a better way to add the predefined types.
* TODO (guptasu): Add them only when required and not in all cases.
*/
static Iterable<Type> createAdditionalServiceTypes() {
Map<String, DescriptorProto> additionalMessages = Maps.newHashMap();
additionalMessages.put(Struct.getDescriptor().getFullName(),
Struct.getDescriptor().toProto());
additionalMessages.put(Value.getDescriptor().getFullName(),
Value.getDescriptor().toProto());
additionalMessages.put(ListValue.getDescriptor().getFullName(),
ListValue.getDescriptor().toProto());
additionalMessages.put(Empty.getDescriptor().getFullName(),
Empty.getDescriptor().toProto());
additionalMessages.put(Int32Value.getDescriptor().getFullName(),
Int32Value.getDescriptor().toProto());
additionalMessages.put(DoubleValue.getDescriptor().getFullName(),
DoubleValue.getDescriptor().toProto());
additionalMessages.put(BoolValue.getDescriptor().getFullName(),
BoolValue.getDescriptor().toProto());
additionalMessages.put(StringValue.getDescriptor().getFullName(),
StringValue.getDescriptor().toProto());
for (Descriptor descriptor : Struct.getDescriptor().getNestedTypes()) {
additionalMessages.put(descriptor.getFullName(), descriptor.toProto());
}
// TODO (guptasu): Remove this hard coding. Without this, creation of Model from Service throws.
// Needs investigation.
String fileName = "struct.proto";
List<Type> additionalTypes = Lists.newArrayList();
for (String typeName : additionalMessages.keySet()) {
additionalTypes.add(TypesBuilderFromDescriptor.createType(typeName,
additionalMessages.get(typeName), fileName));
}
return additionalTypes;
}
/**
* TODO (guptasu): only needed to create hard coded Types (Struct, ListValue, and Value). Check
* if this can be removed. Create the Protobuf.Type instance from descriptorProto.
*/
private static Type createType(String typeName, DescriptorProto descriptorProto,
String fileName) {
Type.Builder coreTypeBuilder = Type.newBuilder().setName(typeName);
int count = 1;
for (FieldDescriptorProto fieldProto : descriptorProto.getFieldList()) {
Field.Kind fieldKind = Field.Kind.valueOf(fieldProto.getType().getNumber());
Cardinality cardinality = Cardinality.CARDINALITY_OPTIONAL;
if (fieldProto.getLabel() == Label.LABEL_REPEATED) {
cardinality = Cardinality.CARDINALITY_REPEATED;
}
Field.Builder coreFieldBuilder = Field
.newBuilder()
.setName(fieldProto.getName())
.setNumber(count++)
.setKind(fieldKind)
.setCardinality(cardinality);
if (fieldKind == Kind.TYPE_MESSAGE || fieldKind == Kind.TYPE_ENUM) {
String typeFullName =
fieldProto.getTypeName().startsWith(".") ? fieldProto.getTypeName().substring(1)
: fieldProto.getTypeName();
coreFieldBuilder.setTypeUrl(TYPE_SERVICE_BASE_URL + typeFullName);
}
coreTypeBuilder.addFields(coreFieldBuilder.build());
}
coreTypeBuilder.setSourceContext(SourceContext.newBuilder().setFileName(fileName));
coreTypeBuilder.setSyntax(Syntax.SYNTAX_PROTO3);
return coreTypeBuilder.build();
}
protected void addFieldToMessageAncestor(
int generationsToSkip,
FieldDescriptorProto.Builder fieldDesc,
SourceCodeInfo.Location location) {
BuilderVisitorNodeInfo ancestorInfo = getAncestorInfo(generationsToSkip);
if (ancestorInfo instanceof MessageNodeInfo) {
((MessageNodeInfo) ancestorInfo).addNewField(fieldDesc, location);
setModified(true);
} else {
throw new RuntimeException(
String.format(
"Tried to add a field to a %s, but can only add to %s",
ancestorInfo.node().getClass(), DescriptorProto.Builder.class));
}
}
@Accepts
protected void accept(DescriptorProto.Builder message) {
MessageNodeInfo messageInfo =
(MessageNodeInfo) pushParent(BuilderVisitorNodeInfo.create(message, currentFile));
visitRepeated(DescriptorProto.FIELD_FIELD_NUMBER);
visitRepeated(DescriptorProto.NESTED_TYPE_FIELD_NUMBER);
visitRepeated(DescriptorProto.ENUM_TYPE_FIELD_NUMBER);
visitRepeated(DescriptorProto.EXTENSION_FIELD_NUMBER);
visit(message.getOptionsBuilder());
popExpectedParent(message);
}
public void processAddedFields(DescriptorProto.Builder message, Iterable<FieldLocation> fields) {
if (manageSourceCodeInfo) {
ProtoPathWrapper messagePath = pathFromElement(message);
if (messagePath == null) {
throw new RuntimeException(
String.format(
"Internal error - couldn't find path for proto message %s",
ProtoHelpers.getName(message)));
}
ProtoPathWrapper fieldsPath =
ProtoHelpers.buildPath(messagePath, DescriptorProto.FIELD_FIELD_NUMBER);
ProtoPathTree<SourceCodeInfo.Location> fieldsPathTree =
pathToLocation.getSubtree(fieldsPath, true);
for (FieldLocation field : fields) {
Integer fieldIndex = fieldsPathTree.size();
if (fieldIndex > 0
&& (fieldsPathTree.firstKey() != 0 || fieldsPathTree.lastKey() != (fieldIndex - 1))) {
throw new RuntimeException(
String.format(
"BuilderVisitor internal error - non-contiguous field indexes found [%d..%d]\n",
fieldsPathTree.firstKey(), fieldsPathTree.lastKey()));
}
fieldsPathTree.addDataElement(
new ProtoPathWrapper(fieldIndex), // relative path of field within this message
field.location());
elementToOriginalPath.put(
field.fieldDescriptor(), ProtoHelpers.buildPath(fieldsPath, fieldIndex));
}
}
}
private void processAddedFields(FileNodeInfo currentFile) {
if (!toBeAddedFields().isEmpty()) {
DescriptorProto.Builder message = (DescriptorProto.Builder) node();
if (currentFile != null) {
currentFile.processAddedFields(message, toBeAddedFields());
}
for (FieldLocation fieldInfo : toBeAddedFields()) {
message.addField(fieldInfo.fieldDescriptor());
}
}
}
/** Determines if the given field number is an extension. */
public boolean isExtensionNumber(final int number) {
for (final DescriptorProto.ExtensionRange range :
proto.getExtensionRangeList()) {
if (range.getStart() <= number && number < range.getEnd()) {
return true;
}
}
return false;
}
/** Determines if the given field number is reserved. */
public boolean isReservedNumber(final int number) {
for (final DescriptorProto.ReservedRange range :
proto.getReservedRangeList()) {
if (range.getStart() <= number && number < range.getEnd()) {
return true;
}
}
return false;
}
protected void decompileMessageBody(DescriptorProto messageDescriptor) throws IOException {
indent++;
if (messageDescriptor.hasOptions()) {
decompileOptions(messageDescriptor.getOptions());
}
decompileMembers(messageDescriptor.getEnumTypeList(),
messageDescriptor.getNestedTypeList(),
messageDescriptor.getFieldList(),
messageDescriptor.getExtensionRangeList(),
messageDescriptor.getExtensionList());
indent--;
indentedFormat("}");
}
protected void findGroups(List<FieldDescriptorProto> fieldDescriptors,
Map<String,DescriptorProto> groups) {
for (FieldDescriptorProto fieldDescriptor : fieldDescriptors) {
if (fieldDescriptor.getType() == Type.TYPE_GROUP) {
groups.put(fieldDescriptor.getTypeName(), null);
}
}
}
protected void decompileFields(List<FieldDescriptorProto> fieldDescriptors,
Map<String,DescriptorProto> groups)
throws IOException {
for (FieldDescriptorProto fieldDescriptor : fieldDescriptors) {
String label = LABELS.get(fieldDescriptor.getLabel());
String type = TYPES.get(fieldDescriptor.getType());
String name = fieldDescriptor.getName();
if (fieldDescriptor.hasTypeName()) {
type = fieldDescriptor.getTypeName();
if ((absolutePackage != null) && type.startsWith(absolutePackage)) {
type = type.substring(absolutePackage.length());
}
}
DescriptorProto groupDescriptor = null;
if (fieldDescriptor.getType() == Type.TYPE_GROUP) {
groupDescriptor = groups.get(type);
if (groupDescriptor != null) {
name = type;
type = "group";
}
}
indentedFormat("%s %s %s = %d",
label, type, name, fieldDescriptor.getNumber());
if (fieldDescriptor.hasOptions() || fieldDescriptor.hasDefaultValue()) {
write(defaultAndOptions(fieldDescriptor.hasOptions() ? fieldDescriptor.getOptions() : null,
fieldDescriptor.hasDefaultValue() ? fieldDescriptor.getDefaultValue() : null));
}
if (groupDescriptor == null) {
write(";");
}
else {
decompileMessageBody(groupDescriptor);
}
}
}
/**
* Tests that the DescriptorValidationException works as intended.
*/
public void testDescriptorValidatorException() throws Exception {
FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder()
.setName("foo.proto")
.addMessageType(DescriptorProto.newBuilder()
.setName("Foo")
.addField(FieldDescriptorProto.newBuilder()
.setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
.setType(FieldDescriptorProto.Type.TYPE_INT32)
.setName("foo")
.setNumber(1)
.setDefaultValue("invalid")
.build())
.build())
.build();
try {
Descriptors.FileDescriptor.buildFrom(fileDescriptorProto,
new FileDescriptor[0]);
fail("DescriptorValidationException expected");
} catch (DescriptorValidationException e) {
// Expected; check that the error message contains some useful hints
assertTrue(e.getMessage().indexOf("foo") != -1);
assertTrue(e.getMessage().indexOf("Foo") != -1);
assertTrue(e.getMessage().indexOf("invalid") != -1);
assertTrue(e.getCause() instanceof NumberFormatException);
assertTrue(e.getCause().getMessage().indexOf("invalid") != -1);
}
}
public void testHiddenDependency() throws Exception {
FileDescriptorProto barProto = FileDescriptorProto.newBuilder()
.setName("bar.proto")
.addMessageType(DescriptorProto.newBuilder().setName("Bar"))
.build();
FileDescriptorProto forwardProto = FileDescriptorProto.newBuilder()
.setName("forward.proto")
.addDependency("bar.proto")
.build();
FileDescriptorProto fooProto = FileDescriptorProto.newBuilder()
.setName("foo.proto")
.addDependency("forward.proto")
.addMessageType(DescriptorProto.newBuilder()
.setName("Foo")
.addField(FieldDescriptorProto.newBuilder()
.setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
.setTypeName("Bar")
.setName("bar")
.setNumber(1)))
.build();
FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom(
barProto, new FileDescriptor[0]);
FileDescriptor forwardFile = Descriptors.FileDescriptor.buildFrom(
forwardProto, new FileDescriptor[] {barFile});
try {
Descriptors.FileDescriptor.buildFrom(
fooProto, new FileDescriptor[] {forwardFile});
fail("DescriptorValidationException expected");
} catch (DescriptorValidationException e) {
assertTrue(e.getMessage().indexOf("Bar") != -1);
assertTrue(e.getMessage().indexOf("is not defined") != -1);
}
}
public void testPublicDependency() throws Exception {
FileDescriptorProto barProto = FileDescriptorProto.newBuilder()
.setName("bar.proto")
.addMessageType(DescriptorProto.newBuilder().setName("Bar"))
.build();
FileDescriptorProto forwardProto = FileDescriptorProto.newBuilder()
.setName("forward.proto")
.addDependency("bar.proto")
.addPublicDependency(0)
.build();
FileDescriptorProto fooProto = FileDescriptorProto.newBuilder()
.setName("foo.proto")
.addDependency("forward.proto")
.addMessageType(DescriptorProto.newBuilder()
.setName("Foo")
.addField(FieldDescriptorProto.newBuilder()
.setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
.setTypeName("Bar")
.setName("bar")
.setNumber(1)))
.build();
FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom(
barProto, new FileDescriptor[0]);
FileDescriptor forwardFile = Descriptors.FileDescriptor.buildFrom(
forwardProto, new FileDescriptor[]{barFile});
Descriptors.FileDescriptor.buildFrom(
fooProto, new FileDescriptor[] {forwardFile});
}
@Nullable
private static String appendMessageToFullName(
DescriptorProto message, List<Integer> path, String fullNameSoFar) {
fullNameSoFar = appendNameComponent(fullNameSoFar, message.getName());
return path.size() > 2 ? appendToFullName(message, path.subList(2, path.size()), fullNameSoFar)
: fullNameSoFar;
}
@Test
public void testPOJODescriptorWorksWell() throws IOException {
Descriptor descriptor2 = AddressBookProtos.Person.getDescriptor();
DescriptorProto proto = descriptor2.toProto();
byte[] byteArray = proto.toByteArray();
Codec<DescriptorProtoPOJO> codec = ProtobufProxy.create(DescriptorProtoPOJO.class, true);
DescriptorProtoPOJO decode = codec.decode(byteArray);
byte[] encode = codec.encode(decode);
Assert.assertArrayEquals(byteArray, encode);
}
@Test
public void testPOJODescriptorWorksWell() throws IOException {
Descriptor descriptor2 =
com.baidu.bjf.remoting.protobuf.complexList.AddressBookProtos.AddressBook.getDescriptor();
DescriptorProto proto = descriptor2.toProto();
byte[] byteArray = proto.toByteArray();
DescriptorProtoPOJO decode = codec.decode(byteArray);
byte[] encode = codec.encode(decode);
Assert.assertArrayEquals(byteArray, encode);
}
public void setSourceMessageDesc(DescriptorProto sourceMessageDesc) {
this.sourceMessageDesc = sourceMessageDesc;
}