Last active
April 12, 2017 20:46
-
-
Save knoguchi/211f44a2137b5def37fbdc04a6db437e to your computer and use it in GitHub Desktop.
Create ProtobufSchema object from .descriptor file
This file contains 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 com.example.jackson.protobuf; | |
import com.fasterxml.jackson.dataformat.protobuf.schema.FieldType; | |
import com.fasterxml.jackson.dataformat.protobuf.schema.ProtobufEnum; | |
import com.fasterxml.jackson.dataformat.protobuf.schema.ProtobufField; | |
import com.fasterxml.jackson.dataformat.protobuf.schema.ProtobufMessage; | |
import com.fasterxml.jackson.dataformat.protobuf.schema.ProtobufSchema; | |
import com.github.os72.protobuf.dynamic.DynamicSchema; | |
import com.google.protobuf.Descriptors; | |
import com.squareup.protoparser.DataType; | |
import com.squareup.protoparser.FieldElement; | |
import com.squareup.protoparser.OptionElement; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
import static com.squareup.protoparser.FieldElement.Label.OPTIONAL; | |
import static com.squareup.protoparser.FieldElement.Label.REPEATED; | |
import static com.squareup.protoparser.FieldElement.Label.REQUIRED; | |
public class DynamicSchemaUtil | |
{ | |
private final static Map<Descriptors.FieldDescriptor.Type, FieldType> typeMap; | |
private final static Map<Descriptors.FieldDescriptor.Type, DataType> typeMap2; | |
static { | |
typeMap = new HashMap(); | |
typeMap.put(Descriptors.FieldDescriptor.Type.DOUBLE, FieldType.DOUBLE); | |
typeMap.put(Descriptors.FieldDescriptor.Type.FLOAT, FieldType.FLOAT); | |
typeMap.put(Descriptors.FieldDescriptor.Type.INT32, FieldType.VINT32_Z); | |
typeMap.put(Descriptors.FieldDescriptor.Type.INT64, FieldType.VINT64_Z); | |
typeMap.put(Descriptors.FieldDescriptor.Type.UINT32, FieldType.VINT32_STD); | |
typeMap.put(Descriptors.FieldDescriptor.Type.UINT64, FieldType.VINT64_STD); | |
typeMap.put(Descriptors.FieldDescriptor.Type.FIXED32, FieldType.FIXINT32); | |
typeMap.put(Descriptors.FieldDescriptor.Type.FIXED64, FieldType.FIXINT64); | |
typeMap.put(Descriptors.FieldDescriptor.Type.BOOL, FieldType.BOOLEAN); | |
typeMap.put(Descriptors.FieldDescriptor.Type.STRING, FieldType.STRING); | |
typeMap.put(Descriptors.FieldDescriptor.Type.BYTES, FieldType.BYTES); | |
typeMap.put(Descriptors.FieldDescriptor.Type.ENUM, FieldType.ENUM); | |
typeMap.put(Descriptors.FieldDescriptor.Type.MESSAGE, FieldType.MESSAGE); | |
typeMap2 = new HashMap(); | |
typeMap2.put(Descriptors.FieldDescriptor.Type.BOOL, DataType.ScalarType.BOOL); | |
typeMap2.put(Descriptors.FieldDescriptor.Type.BYTES, DataType.ScalarType.BYTES); | |
typeMap2.put(Descriptors.FieldDescriptor.Type.DOUBLE, DataType.ScalarType.DOUBLE); | |
typeMap2.put(Descriptors.FieldDescriptor.Type.FLOAT, DataType.ScalarType.FLOAT); | |
typeMap2.put(Descriptors.FieldDescriptor.Type.FIXED32, DataType.ScalarType.FIXED32); | |
typeMap2.put(Descriptors.FieldDescriptor.Type.FIXED64, DataType.ScalarType.FIXED64); | |
typeMap2.put(Descriptors.FieldDescriptor.Type.INT32, DataType.ScalarType.INT32); | |
typeMap2.put(Descriptors.FieldDescriptor.Type.INT64, DataType.ScalarType.INT64); | |
typeMap2.put(Descriptors.FieldDescriptor.Type.SFIXED32, DataType.ScalarType.SFIXED32); | |
typeMap2.put(Descriptors.FieldDescriptor.Type.SFIXED64, DataType.ScalarType.SFIXED64); | |
typeMap2.put(Descriptors.FieldDescriptor.Type.SINT32, DataType.ScalarType.SINT32); | |
typeMap2.put(Descriptors.FieldDescriptor.Type.SINT64, DataType.ScalarType.SINT64); | |
typeMap2.put(Descriptors.FieldDescriptor.Type.STRING, DataType.ScalarType.STRING); | |
typeMap2.put(Descriptors.FieldDescriptor.Type.UINT32, DataType.ScalarType.UINT32); | |
typeMap2.put(Descriptors.FieldDescriptor.Type.UINT64, DataType.ScalarType.UINT64); | |
} | |
public static FieldElement.Label getLabel(Descriptors.FieldDescriptor d) | |
{ | |
FieldElement.Label label = REQUIRED; | |
if (d.isOptional()) { | |
label = OPTIONAL; | |
} else if (d.isRequired()) { | |
label = REQUIRED; | |
} else if (d.isRepeated()) { | |
label = REPEATED; | |
} | |
return label; | |
} | |
public static ProtobufEnum buildProtobufEnum(Descriptors.FieldDescriptor d) | |
{ | |
Descriptors.EnumDescriptor enumField = d.getEnumType(); | |
Map<String, Integer> enumFields = new HashMap(); | |
List<Descriptors.EnumValueDescriptor> values = enumField.getValues(); | |
boolean standardIndexing = true; | |
ProtobufEnum et = new ProtobufEnum(d.getName(), enumFields, standardIndexing); | |
return et; | |
} | |
public static ProtobufMessage buildProtobufMessage(Descriptors.Descriptor messageDescriptor) | |
{ | |
List<Descriptors.FieldDescriptor> fieldDescriptors = messageDescriptor.getFields(); | |
ProtobufField[] fields = new ProtobufField[fieldDescriptors.size()]; | |
for (Descriptors.FieldDescriptor d : fieldDescriptors) { | |
ProtobufField f; | |
FieldElement.Label label = getLabel(d); | |
Integer tag = d.getNumber(); | |
// type | |
if (d.getType() == Descriptors.FieldDescriptor.Type.ENUM) { | |
// enum | |
// field | |
FieldElement.Builder builder = FieldElement.builder(); | |
FieldElement nativeField = builder.label(getLabel(d)) | |
.type(DataType.NamedType.create(d.getJsonName())) | |
.name(d.getName()) | |
.tag(tag) | |
.build(); | |
// value | |
ProtobufEnum et = buildProtobufEnum(d); | |
f = new ProtobufField(nativeField, et); | |
} else if (d.getType() == Descriptors.FieldDescriptor.Type.MESSAGE) { | |
// Message | |
FieldElement.Builder builder = FieldElement.builder(); | |
FieldElement nativeField = builder.label(getLabel(d)) | |
.type(DataType.NamedType.create(d.getJsonName())) | |
.name(d.getName()) | |
.tag(tag) | |
.build(); | |
// value | |
ProtobufMessage nestedMsg = buildProtobufMessage(d.getMessageType()); | |
f = new ProtobufField(nativeField, nestedMsg); | |
} else if (d.getType() == Descriptors.FieldDescriptor.Type.GROUP) { | |
System.out.println("not supported"); | |
continue; | |
} else { | |
// scalar | |
// field | |
FieldElement.Builder builder = FieldElement.builder(); | |
FieldElement nativeField = builder.label(label) | |
.type(typeMap2.get(d.getType())) | |
.name(d.getName()) | |
.tag(tag) | |
.addOption(OptionElement.create("packed", OptionElement.Kind.BOOLEAN, d.isPacked())) | |
.build(); | |
// value | |
FieldType t = typeMap.get(d.getType()); | |
f = new ProtobufField(nativeField, t); | |
} | |
fields[d.getIndex()] = f; | |
} | |
return new ProtobufMessage(messageDescriptor.getName(), fields); | |
} | |
public static ProtobufSchema toProtobufSchema(DynamicSchema dynamicSchema, String rootType) | |
{ | |
Descriptors.Descriptor messageDescriptor = dynamicSchema.getMessageDescriptor(rootType); | |
ProtobufMessage msg = buildProtobufMessage(messageDescriptor); | |
return new ProtobufSchema(msg); | |
} | |
public static ProtobufSchema toProtobufSchema(DynamicSchema dynamicSchema) | |
{ | |
String firstType = (String) dynamicSchema.getMessageTypes().toArray()[0]; | |
return toProtobufSchema(dynamicSchema, firstType); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment