下面列出了com.google.protobuf.Descriptors.DescriptorValidationException#com.google.protobuf.Descriptors.EnumDescriptor 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private Object getValueForField(FieldDescriptor field, Object value, Message.Builder builder) {
// TODO: handle groups, oneof
if (field.getType() == FieldDescriptor.Type.MESSAGE) {
Descriptor fieldTypeDescriptor =
descriptorMapping.get(getReferenceName(field.getMessageType()));
return createProtoBuf(
fieldTypeDescriptor, builder.newBuilderForField(field), (Map<String, Object>) value);
}
if (field.getType() == FieldDescriptor.Type.ENUM) {
EnumDescriptor enumDescriptor =
enumMapping.get(ProtoToGql.getReferenceName(field.getEnumType()));
return enumDescriptor.findValueByName(value.toString());
}
if (field.getType() == FieldDescriptor.Type.FLOAT) {
if (value instanceof Double) {
return ((Double) value).floatValue();
}
}
return value;
}
public GqlInputConverter build() {
HashBiMap<String, Descriptor> mapping = HashBiMap.create();
HashBiMap<String, EnumDescriptor> enumMapping = HashBiMap.create(getEnumMap(enumDescriptors));
LinkedList<Descriptor> loop = new LinkedList<>(descriptors);
Set<FileDescriptor> fileDescriptorSet = ProtoRegistry.extractDependencies(fileDescriptors);
for (FileDescriptor fileDescriptor : fileDescriptorSet) {
loop.addAll(fileDescriptor.getMessageTypes());
enumMapping.putAll(getEnumMap(fileDescriptor.getEnumTypes()));
}
while (!loop.isEmpty()) {
Descriptor descriptor = loop.pop();
if (!mapping.containsKey(descriptor.getFullName())) {
mapping.put(getReferenceName(descriptor), descriptor);
loop.addAll(descriptor.getNestedTypes());
enumMapping.putAll(getEnumMap(descriptor.getEnumTypes()));
}
}
return new GqlInputConverter(
ImmutableBiMap.copyOf(mapping), ImmutableBiMap.copyOf(enumMapping));
}
/**
* Parse Enum value {@link EnumValueDescriptor} associated with given {@link EnumDescriptor} from
* given text if found. Otherwise, throw a {@link ParseException}.
*
* <p>The text could be either enum value name or enum value number.
*/
static EnumValueDescriptor parseEnum(EnumDescriptor enumType, String text) {
EnumValueDescriptor value = null;
if (lookingAtNumber(text)) {
int number = parseUInt32(text);
value = enumType.findValueByNumber(number);
if (value == null) {
throw new ParseException(String.format(
"Enum type '%s' has no value with number %d", enumType.getFullName(), number));
}
} else {
value = enumType.findValueByName(text);
if (value == null) {
throw new ParseException(String.format(
"Enum type '%s' has no value with name '%s'", enumType.getFullName(), text));
}
}
return value;
}
/**
* Finds an enum value in the given {@link EnumDescriptor} that matches the given JSON element,
* either by name if the current adapter is using {@link EnumSerialization#NAME}, otherwise by
* number. If matching by name, it uses the extension value if it is defined, otherwise it uses
* its default value.
*
* @throws IllegalArgumentException if a matching name/number was not found
*/
private EnumValueDescriptor findValueByNameAndExtension(EnumDescriptor desc,
JsonElement jsonElement) {
if (enumSerialization == EnumSerialization.NAME) {
// With enum name
for (EnumValueDescriptor enumDesc : desc.getValues()) {
String enumValue = getCustSerializedEnumValue(enumDesc.getOptions(), enumDesc.getName());
if (enumValue.equals(jsonElement.getAsString())) {
return enumDesc;
}
}
throw new IllegalArgumentException(
String.format("Unrecognized enum name: %s", jsonElement.getAsString()));
} else {
// With enum value
EnumValueDescriptor fieldValue = desc.findValueByNumber(jsonElement.getAsInt());
if (fieldValue == null) {
throw new IllegalArgumentException(
String.format("Unrecognized enum value: %s", jsonElement.getAsInt()));
}
return fieldValue;
}
}
private void generateProtoFromDescriptor(Descriptor descriptor,
Appendable out, String indent, Map<Descriptor, Boolean> descriptors)
throws IOException {
descriptors.put(descriptor, true);
out.append(indent + "message " + descriptor.getName() + " {\n");
for (FieldDescriptor fieldDescriptor : descriptor.getFields()) {
generateProtoFromDescriptor(fieldDescriptor, out, indent + " ",
descriptors);
}
for (Descriptor nested : descriptor.getNestedTypes()) {
generateProtoFromDescriptor(nested, out, indent + " ",
descriptors);
}
for (EnumDescriptor enumDescriptor : descriptor.getEnumTypes()) {
generateProtoFromDescriptor(enumDescriptor, out, indent + " ");
}
out.append(indent + "}\n");
}
private void validateEnum(@Nonnull String fieldName, @Nonnull EnumDescriptor oldEnumDescriptor, @Nonnull EnumDescriptor newEnumDescriptor) {
for (Descriptors.EnumValueDescriptor oldEnumValue : oldEnumDescriptor.getValues()) {
Descriptors.EnumValueDescriptor newEnumValue = newEnumDescriptor.findValueByNumber(oldEnumValue.getNumber());
if (newEnumValue == null) {
throw new MetaDataException("enum removes value",
LogMessageKeys.FIELD_NAME, fieldName);
}
}
}
static GraphQLEnumType convert(
EnumDescriptor descriptor, SchemaOptions schemaOptions) {
GraphQLEnumType.Builder builder = GraphQLEnumType.newEnum().name(getReferenceName(descriptor));
for (EnumValueDescriptor value : descriptor.getValues()) {
builder.value(
value.getName(),
value.getName(),
schemaOptions.commentsMap().get(value.getFullName()),
value.getOptions().getDeprecated() ? "deprecated in proto" : null);
}
return builder.build();
}
private static BiMap<String, EnumDescriptor> getEnumMap(Iterable<EnumDescriptor> descriptors) {
HashBiMap<String, EnumDescriptor> mapping = HashBiMap.create();
for (EnumDescriptor enumDescriptor : descriptors) {
mapping.put(ProtoToGql.getReferenceName(enumDescriptor), enumDescriptor);
}
return mapping;
}
private static BiMap<String, GraphQLType> getMap(
List<FileDescriptor> fileDescriptors,
List<Descriptor> descriptors,
List<EnumDescriptor> enumDescriptors,
GraphQLInterfaceType nodeInterface,
SchemaOptions schemaOptions) {
HashBiMap<String, GraphQLType> mapping =
HashBiMap.create(getEnumMap(enumDescriptors, schemaOptions));
LinkedList<Descriptor> loop = new LinkedList<>(descriptors);
Set<FileDescriptor> fileDescriptorSet = extractDependencies(fileDescriptors);
for (FileDescriptor fileDescriptor : fileDescriptorSet) {
loop.addAll(fileDescriptor.getMessageTypes());
mapping.putAll(getEnumMap(fileDescriptor.getEnumTypes(), schemaOptions));
}
while (!loop.isEmpty()) {
Descriptor descriptor = loop.pop();
if (!mapping.containsKey(descriptor.getFullName())) {
mapping.put(
ProtoToGql.getReferenceName(descriptor),
ProtoToGql.convert(descriptor, nodeInterface, schemaOptions));
GqlInputConverter inputConverter =
GqlInputConverter.newBuilder().add(descriptor.getFile()).build();
mapping.put(
GqlInputConverter.getReferenceName(descriptor),
inputConverter.getInputType(descriptor, schemaOptions));
loop.addAll(descriptor.getNestedTypes());
mapping.putAll(getEnumMap(descriptor.getEnumTypes(), schemaOptions));
}
}
return ImmutableBiMap.copyOf(mapping);
}
private static BiMap<String, GraphQLType> getEnumMap(
Iterable<EnumDescriptor> descriptors, SchemaOptions schemaOptions) {
HashBiMap<String, GraphQLType> mapping = HashBiMap.create();
for (EnumDescriptor enumDescriptor : descriptors) {
mapping.put(
ProtoToGql.getReferenceName(enumDescriptor),
ProtoToGql.convert(enumDescriptor, schemaOptions));
}
return mapping;
}
public static void printRepeatedEnum(
List<Integer> values, JsonGenerator gen, EnumDescriptor descriptor) throws IOException {
int numElements = values.size();
gen.writeStartArray(numElements);
for (int i = 0; i < numElements; i++) {
printEnum(values.get(i), gen, descriptor);
}
gen.writeEndArray();
}
public static void printEnum(int value, JsonGenerator gen, EnumDescriptor descriptor)
throws IOException {
EnumValueDescriptor valueDescriptor = descriptor.findValueByNumber(value);
if (valueDescriptor == null) {
gen.writeNumber(value);
} else {
gen.writeString(valueDescriptor.getName());
}
}
public void testEnumDescriptor() throws Exception {
EnumDescriptor enumType = ForeignEnum.getDescriptor();
EnumDescriptor nestedType = TestAllTypes.NestedEnum.getDescriptor();
assertEquals("ForeignEnum", enumType.getName());
assertEquals("protobuf_unittest.ForeignEnum", enumType.getFullName());
assertEquals(UnittestProto.getDescriptor(), enumType.getFile());
assertNull(enumType.getContainingType());
assertEquals(DescriptorProtos.EnumOptions.getDefaultInstance(),
enumType.getOptions());
assertEquals("NestedEnum", nestedType.getName());
assertEquals("protobuf_unittest.TestAllTypes.NestedEnum",
nestedType.getFullName());
assertEquals(UnittestProto.getDescriptor(), nestedType.getFile());
assertEquals(TestAllTypes.getDescriptor(), nestedType.getContainingType());
EnumValueDescriptor value = ForeignEnum.FOREIGN_FOO.getValueDescriptor();
assertEquals(value, enumType.getValues().get(0));
assertEquals("FOREIGN_FOO", value.getName());
assertEquals(4, value.getNumber());
assertEquals(value, enumType.findValueByName("FOREIGN_FOO"));
assertEquals(value, enumType.findValueByNumber(4));
assertNull(enumType.findValueByName("NO_SUCH_VALUE"));
for (int i = 0; i < enumType.getValues().size(); i++) {
assertEquals(i, enumType.getValues().get(i).getIndex());
}
}
private DynamicSchema(FileDescriptorSet fileDescSet) throws DescriptorValidationException {
mFileDescSet = fileDescSet;
Map<String,FileDescriptor> fileDescMap = init(fileDescSet);
Set<String> msgDupes = new HashSet<String>();
Set<String> enumDupes = new HashSet<String>();
for (FileDescriptor fileDesc : fileDescMap.values()) {
for (Descriptor msgType : fileDesc.getMessageTypes()) addMessageType(msgType, null, msgDupes, enumDupes);
for (EnumDescriptor enumType : fileDesc.getEnumTypes()) addEnumType(enumType, null, enumDupes);
}
for (String msgName : msgDupes) mMsgDescriptorMapShort.remove(msgName);
for (String enumName : enumDupes) mEnumDescriptorMapShort.remove(enumName);
}
private void addMessageType(Descriptor msgType, String scope, Set<String> msgDupes, Set<String> enumDupes) {
String msgTypeNameFull = msgType.getFullName();
String msgTypeNameShort = (scope == null ? msgType.getName() : scope + "." + msgType.getName());
if (mMsgDescriptorMapFull.containsKey(msgTypeNameFull)) throw new IllegalArgumentException("duplicate name: " + msgTypeNameFull);
if (mMsgDescriptorMapShort.containsKey(msgTypeNameShort)) msgDupes.add(msgTypeNameShort);
mMsgDescriptorMapFull.put(msgTypeNameFull, msgType);
mMsgDescriptorMapShort.put(msgTypeNameShort, msgType);
for (Descriptor nestedType : msgType.getNestedTypes()) addMessageType(nestedType, msgTypeNameShort, msgDupes, enumDupes);
for (EnumDescriptor enumType : msgType.getEnumTypes()) addEnumType(enumType, msgTypeNameShort, enumDupes);
}
private void addEnumType(EnumDescriptor enumType, String scope, Set<String> enumDupes) {
String enumTypeNameFull = enumType.getFullName();
String enumTypeNameShort = (scope == null ? enumType.getName() : scope + "." + enumType.getName());
if (mEnumDescriptorMapFull.containsKey(enumTypeNameFull)) throw new IllegalArgumentException("duplicate name: " + enumTypeNameFull);
if (mEnumDescriptorMapShort.containsKey(enumTypeNameShort)) enumDupes.add(enumTypeNameShort);
mEnumDescriptorMapFull.put(enumTypeNameFull, enumType);
mEnumDescriptorMapShort.put(enumTypeNameShort, enumType);
}
@VisibleForTesting
EnumInfo newEnumInfo(EnumDescriptor enumDescriptor) {
return new EnumInfo(
enumDescriptor.getFullName(),
enumDescriptor.getValues().stream()
.map(d -> new EnumValueInfo(d.getName(), d.getNumber()))
.collect(toImmutableList()));
}
/**
* @return the set of all enums referred to be this message and its nested
* messages. Enum references are due to message-typed fields.
*/
public List<ProtoEnum> getReferencedEnums() {
if (referencedEnums == null) {
referencedEnums = Lists.newArrayList();
for (EnumDescriptor d : collectEnums(descriptor, Sets.<EnumDescriptor> newLinkedHashSet())) {
referencedEnums.add(adapt(d));
}
}
return referencedEnums;
}
/**
* Collects enums referred to by a message and its nested messages.
*
* @return {@code referenced}
*/
private static Collection<EnumDescriptor> collectEnums(
Descriptor d, Collection<EnumDescriptor> referenced) {
for (FieldDescriptor fd : d.getFields()) {
if (fd.getJavaType() == JavaType.ENUM) {
referenced.add(fd.getEnumType());
}
}
for (Descriptor nd : d.getNestedTypes()) {
collectEnums(nd, referenced);
}
return referenced;
}
/**
* @return the nested enums of the message
*/
public List<ProtoEnum> getNestedEnums() {
if (enums == null) {
ImmutableList.Builder<ProtoEnum> builder = ImmutableList.builder();
for (EnumDescriptor ed : descriptor.getEnumTypes()) {
builder.add(adapt(ed));
}
enums = builder.build();
}
return enums;
}
public void testEnumDescriptor() throws Exception {
Descriptor descriptor = TypicalData.Builder.getDescriptor();
FieldDescriptor fieldDescriptor = descriptor.findFieldByNumber(3);
assertEquals(Type.ENUM, fieldDescriptor.getType());
EnumDescriptor enumDescriptor = fieldDescriptor.getEnumType();
assertNotNull(enumDescriptor);
EnumValueDescriptor enumValueDescriptor = enumDescriptor.findValueByNumber(1);
assertEquals(1, enumValueDescriptor.getNumber());
assertEquals("VALUE1", enumValueDescriptor.getName());
}
private static String indexRange(EnumDescriptor field) {
List<Integer> indices = Lists.transform(field.getValues(), new Function<EnumValueDescriptor, Integer>() {
@Override
public Integer apply(@Nonnull EnumValueDescriptor value) {
return value.getIndex();
}
});
// Guava returns non-modifiable list
indices = Lists.newArrayList(indices);
Collections.sort(indices);
return "[" + Joiner.on(',').join(indices) + "]";
}
/**
* @return the set of all enums referred to be this message and its nested
* messages. Enum references are due to message-typed fields.
*/
public List<ProtoEnum> getReferencedEnums() {
if (referencedEnums == null) {
referencedEnums = Lists.newArrayList();
for (EnumDescriptor d : collectEnums(descriptor, Sets.<EnumDescriptor> newLinkedHashSet())) {
referencedEnums.add(adapt(d));
}
}
return referencedEnums;
}
/**
* Collects enums referred to by a message and its nested messages.
*
* @return {@code referenced}
*/
private static Collection<EnumDescriptor> collectEnums(
Descriptor d, Collection<EnumDescriptor> referenced) {
for (FieldDescriptor fd : d.getFields()) {
if (fd.getJavaType() == JavaType.ENUM) {
referenced.add(fd.getEnumType());
}
}
for (Descriptor nd : d.getNestedTypes()) {
collectEnums(nd, referenced);
}
return referenced;
}
/**
* @return the nested enums of the message
*/
public List<ProtoEnum> getNestedEnums() {
if (enums == null) {
ImmutableList.Builder<ProtoEnum> builder = ImmutableList.builder();
for (EnumDescriptor ed : descriptor.getEnumTypes()) {
builder.add(adapt(ed));
}
enums = builder.build();
}
return enums;
}
private void generateProtoFromDescriptor(EnumDescriptor descriptor,
Appendable out, String indent) throws IOException {
out.append(indent + "enum " + descriptor.getName() + " {\n");
for (EnumValueDescriptor valueDescriptor : descriptor.getValues()) {
generateProtoFromDescriptor(valueDescriptor, out, indent + " ");
}
out.append(indent + "}\n");
}
public void generateProtoFromDescriptor(FileDescriptor descriptor,
Appendable out, Descriptor wrapperMessage) throws IOException {
String package1 = descriptor.getPackage();
if (package1 != null) {
out.append("package " + package1 + ";\n");
}
FileOptions options = descriptor.getOptions();
String javaPackage = options.getJavaPackage();
if (javaPackage != null) {
out.append("option java_package = \"" + javaPackage + "\";\n");
}
String javaOuterClassname = options.getJavaOuterClassname();
if (javaOuterClassname != null) {
out.append("option java_outer_classname = \"" + javaOuterClassname
+ "\";\n");
}
for (ServiceDescriptor serviceDescriptor : descriptor.getServices()) {
generateProtoFromDescriptor(serviceDescriptor, out);
}
for (Descriptor messageDescriptor : descriptor.getMessageTypes()) {
if (wrapperMessage != null && messageDescriptor.equals(wrapperMessage)) {
out.append("// This is the message you can send to this service (wrapper message):\n");
}
generateProtoFromDescriptor(messageDescriptor, out, "",
new LinkedHashMap<Descriptor, Boolean>());
}
for (EnumDescriptor enumDescriptor : descriptor.getEnumTypes()) {
generateProtoFromDescriptor(enumDescriptor, out, "");
}
}
private static Object handlePrimitive(Tokenizer tokenizer, FieldDescriptor field,
boolean selfType)
throws ParseException {
Object value = null;
if ("null".equals(tokenizer.currentToken())) {
tokenizer.consume("null");
return value;
}
switch (field.getType()) {
case INT32:
case SINT32:
case SFIXED32:
value = tokenizer.consumeInt32();
break;
case INT64:
case SINT64:
case SFIXED64:
value = tokenizer.consumeInt64();
break;
case UINT32:
case FIXED32:
value = tokenizer.consumeUInt32();
break;
case UINT64:
case FIXED64:
value = tokenizer.consumeUInt64();
break;
case FLOAT:
value = tokenizer.consumeFloat();
break;
case DOUBLE:
value = tokenizer.consumeDouble();
break;
case BOOL:
value = tokenizer.consumeBoolean();
break;
case STRING:
value = tokenizer.consumeString();
break;
case BYTES:
value = tokenizer.consumeByteString(field.getFullName(), selfType);
break;
case ENUM: {
EnumDescriptor enumType = field.getEnumType();
if (tokenizer.lookingAtInteger()) {
int number = tokenizer.consumeInt32();
value = enumType.findValueByNumber(number);
if (value == null) {
throw tokenizer.parseExceptionPreviousToken("Enum type \""
+ enumType.getFullName()
+ "\" has no value with number "
+ number + ".");
}
} else {
String id = tokenizer.consumeIdentifier();
if (StringUtils.isAllLowerCase(id)) {
char b = id.charAt(0);
b = (char) (b + 'A' - 'a');
String s = id.substring(1);
id = b + s;
}
value = enumType.findValueByName(id);
if (value == null) {
throw tokenizer.parseExceptionPreviousToken("Enum type \""
+ enumType.getFullName()
+ "\" has no value named \""
+ id + "\".");
}
}
break;
}
case MESSAGE:
case GROUP:
throw new RuntimeException("Can't get here.");
default:
}
return value;
}
static Object objToMessageObjInner(Builder b, Object value, FieldDescriptor field, boolean isRepeated) {
switch (field.getType()) {
case INT32:
case SINT32:
case SFIXED32:
return TypeSafe.anyToInt(value);
case INT64:
case SINT64:
case SFIXED64:
if( value instanceof Date)
return ((Date)value).getTime();
return TypeSafe.anyToLong(value);
case BOOL:
return TypeSafe.anyToBool(value);
case FLOAT:
return TypeSafe.anyToFloat(value);
case DOUBLE:
return TypeSafe.anyToDouble(value);
case UINT32:
case FIXED32:
return (int) (TypeSafe.anyToLong(value) & 0x00000000FFFFFFFFL);
case UINT64:
case FIXED64:
BigInteger bi = new BigInteger(value.toString());
return bi.longValue();
case STRING:
if( value instanceof Date)
return formatDate((Date)value);
return TypeSafe.anyToString(value);
case BYTES: {
if (value instanceof ByteString) {
return value;
}
if (value instanceof String) {
byte[] bb = getBytes((String) value);
if (bb == null) return null;
return ByteString.copyFrom(bb);
}
if (value instanceof byte[]) {
return ByteString.copyFrom((byte[]) value);
}
return null;
}
case ENUM: {
EnumDescriptor ed = field.getEnumType();
EnumValueDescriptor evd = ed.findValueByName(value.toString());
if (evd == null) {
evd = ed.findValueByNumber(TypeSafe.anyToInt(value));
}
if (evd == null) return null;
return evd;
}
case MESSAGE:
Map<String, Object> map = TypeSafe.anyToMap(value);
if (map == null) {
if( value instanceof MapConvertable) {
map = ((MapConvertable)value).toMap();
}
if( map == null ) {
return null;
}
}
Builder b2 = isRepeated ?
getRepeatedFieldBuilder(b, field.getName()) :
getFieldBuilder(b, field);
for (FieldDescriptor subfield : b2.getDescriptorForType().getFields()) {
String subName = subfield.getName();
Object subValue = getValue(map, null, subName);
if (subValue == null) continue;
if (subfield.isRepeated()) {
objToMessageObjRepeated(b2, subValue, subfield);
} else {
objToMessageObj(b2, subValue, subfield);
}
}
return isRepeated ? null : b2.build();
default:
return null;
}
}
private static Object randomEnum(EnumDescriptor enumDescriptor) {
List<EnumValueDescriptor> enumConstants = enumDescriptor.getValues();
return enumConstants.get(RAND.nextInt(enumConstants.size()));
}