Skip to content

Instantly share code, notes, and snippets.

@knoguchi
Last active April 12, 2017 20:46
Show Gist options
  • Save knoguchi/211f44a2137b5def37fbdc04a6db437e to your computer and use it in GitHub Desktop.
Save knoguchi/211f44a2137b5def37fbdc04a6db437e to your computer and use it in GitHub Desktop.
Create ProtobufSchema object from .descriptor file
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