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.findValueByNumber((int) value); } return value; }
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)); }
private EnumValueDescriptor parseEnum(EnumDescriptor enumDescriptor, JsonElement json) throws InvalidProtocolBufferException { String value = json.getAsString(); EnumValueDescriptor result = enumDescriptor.findValueByName(value); if (result == null) { // Try to interpret the value as a number. try { int numericValue = parseInt32(json); if (enumDescriptor.getFile().getSyntax() == FileDescriptor.Syntax.PROTO3) { result = enumDescriptor.findValueByNumberCreatingIfUnknown(numericValue); } else { result = enumDescriptor.findValueByNumber(numericValue); } } catch (InvalidProtocolBufferException e) { // Fall through. This exception is about invalid int32 value we get from parseInt32() but // that's not the exception we want the user to see. Since result == null, we will throw // an exception later. } if (result == null) { throw new InvalidProtocolBufferException( "Invalid enum value: " + value + " for enum type: " + enumDescriptor.getFullName()); } } return result; }
/** * 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; }
private SoyType doGetType(String name, SoyTypeRegistry typeRegistry, GenericDescriptor descriptor) { SoyType type; synchronized (lock) { type = typeCache.get(name); if (type == null) { if (descriptor instanceof EnumDescriptor) { type = new SoyProtoEnumType((EnumDescriptor) descriptor); } else { type = new SoyProtoType(typeRegistry, (Descriptor) descriptor, extensions.get(name)); } typeCache.put(name, type); } } return type; }
final void walkDescriptor(GenericDescriptor descriptor) { if (!visited.add(descriptor.getFullName())) { // skip if we have already seen this descriptor return; } if (descriptor instanceof FileDescriptor) { walkFileDescriptor((FileDescriptor) descriptor); } else if (descriptor instanceof Descriptor) { walkMessageDescriptor((Descriptor) descriptor); } else if (descriptor instanceof FieldDescriptor) { FieldDescriptor fieldDescriptor = (FieldDescriptor) descriptor; if (fieldDescriptor.isExtension()) { visitExtensionDescriptor(fieldDescriptor); } else { visitFieldDescriptor(fieldDescriptor); } } else if (descriptor instanceof EnumDescriptor) { visitEnumDescriptor((EnumDescriptor) descriptor); } // services, etc. not needed thus far so neither gathered nor dispatched }
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"); }
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()); } }
static GraphQLEnumType convert(EnumDescriptor descriptor) { GraphQLEnumType.Builder builder = GraphQLEnumType.newEnum().name(getReferenceName(descriptor)); for (EnumValueDescriptor value : descriptor.getValues()) { builder.value(value.getName()); } 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) { HashBiMap<String, GraphQLType> mapping = HashBiMap.create(getEnumMap(enumDescriptors)); LinkedList<Descriptor> loop = new LinkedList<>(descriptors); Set<FileDescriptor> fileDescriptorSet = extractDependencies(fileDescriptors); for (FileDescriptor fileDescriptor : fileDescriptorSet) { loop.addAll(fileDescriptor.getMessageTypes()); mapping.putAll(getEnumMap(fileDescriptor.getEnumTypes())); } while (!loop.isEmpty()) { Descriptor descriptor = loop.pop(); if (!mapping.containsKey(descriptor.getFullName())) { mapping.put( ProtoToGql.getReferenceName(descriptor), ProtoToGql.convert(descriptor, nodeInterface)); GqlInputConverter inputConverter = GqlInputConverter.newBuilder().add(descriptor.getFile()).build(); mapping.put( GqlInputConverter.getReferenceName(descriptor), inputConverter.getInputType(descriptor)); loop.addAll(descriptor.getNestedTypes()); mapping.putAll(getEnumMap(descriptor.getEnumTypes())); } } return ImmutableBiMap.copyOf(mapping); }
private static BiMap<String, GraphQLType> getEnumMap(Iterable<EnumDescriptor> descriptors) { HashBiMap<String, GraphQLType> mapping = HashBiMap.create(); for (EnumDescriptor enumDescriptor : descriptors) { mapping.put( ProtoToGql.getReferenceName(enumDescriptor), ProtoToGql.convert(enumDescriptor)); } return mapping; }
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(); }
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()); } }
/** * @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 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); }
public void testSettersForRepeatedEnumField() throws Exception { DynamicMessage.Builder builder = DynamicMessage.newBuilder(TestAllTypes.getDescriptor()); FieldDescriptor repeatedEnumField = TestAllTypes.getDescriptor().findFieldByName( "repeated_nested_enum"); EnumDescriptor enumDescriptor = TestAllTypes.NestedEnum.getDescriptor(); builder.setField(repeatedEnumField, enumDescriptor.getValues()); DynamicMessage message = builder.build(); assertEquals( enumDescriptor.getValues(), message.getField(repeatedEnumField)); }
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("FOREIGN_FOO", value.toString()); 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()); } }
@VisibleForTesting EnumInfo newEnumInfo(EnumDescriptor enumDescriptor) { return new EnumInfo( enumDescriptor.getFullName(), enumDescriptor.getValues().stream() .map(d -> new EnumValueInfo(d.getName())) .collect(toImmutableList())); }
private NameContext resolveName(final String name, final FileDescriptor fileProto, final Map<String, NameContext> cache) { NameContext nameContext = cache.get(name); if (nameContext != null) { return nameContext; } final EnumDescriptor enumDesc = fileProto.findEnumTypeByName(name); if (enumDesc != null) { nameContext = NameContext.newResolvedInstance(enumDesc.getFullName(), true); } else { final Descriptor descriptor = fileProto.findMessageTypeByName(name); if (descriptor != null) { nameContext = NameContext.newResolvedInstance(descriptor.getFullName(), false); } } if ((nameContext == null) && !fileProto.getMessageTypes().isEmpty()) { nameContext = resolveName(name, fileProto.getMessageTypes()); } if (nameContext == null) { nameContext = NameContext.emptyInstance(); } cache.put(name, nameContext); return nameContext; }
private NameContext resolveName(final String name, final List<Descriptor> messageTypes) { for (final Descriptor descriptor : messageTypes) { final EnumDescriptor enumDesc = descriptor.findEnumTypeByName(name); if (enumDesc != null) { return NameContext.newResolvedInstance(enumDesc.getFullName(), true); } final Descriptor messageDesc = descriptor.findNestedTypeByName(name); if (messageDesc != null) { return NameContext.newResolvedInstance(messageDesc.getFullName(), false); } if (descriptor.getNestedTypes().isEmpty()) { continue; } final NameContext nameContext = resolveName(name, descriptor.getNestedTypes()); if (nameContext != null) { return nameContext; } } return null; }
/** Returns the {@link MethodRef} for the generated forNumber method. */ private static MethodRef getForNumberMethod(EnumDescriptor descriptor) { TypeInfo enumType = enumRuntimeType(descriptor); return MethodRef.createStaticMethod( enumType, new Method("forNumber", enumType.type(), ONE_INT_ARG)) // Note: Enum.forNumber() returns null if there is no corresponding enum. If a bad value is // passed in (via unknown types), the generated bytecode will NPE. .asNonNullable() .asCheap(); }
private static String classNameWithoutPackage(EnumDescriptor descriptor) { // Doesn't append "Mutable" for enum type's name. Descriptor messageDescriptor = descriptor.getContainingType(); if (messageDescriptor == null) { return descriptor.getName(); } return classNameWithoutPackage(messageDescriptor) + '.' + descriptor.getName(); }
public void testUnknownEnumValuesInReflectionApi() throws Exception { Descriptor descriptor = TestMap.getDescriptor(); EnumDescriptor enumDescriptor = TestMap.EnumValue.getDescriptor(); FieldDescriptor field = descriptor.findFieldByName("int32_to_enum_field"); Map<Integer, Integer> data = newMap( 0, 0, 1, 1, 2, 1000); // unknown value TestMap.Builder builder = TestMap.newBuilder() .putAllInt32ToEnumFieldValue(data); // Try to read unknown enum values using reflection API. for (int i = 0; i < builder.getRepeatedFieldCount(field); i++) { Message mapEntry = (Message) builder.getRepeatedField(field, i); int key = ((Integer) getFieldValue(mapEntry, "key")).intValue(); int value = ((EnumValueDescriptor) getFieldValue(mapEntry, "value")).getNumber(); assertEquals(data.get(key).intValue(), value); Message.Builder mapEntryBuilder = mapEntry.toBuilder(); // Increase the value by 1. setFieldValue(mapEntryBuilder, "value", enumDescriptor.findValueByNumberCreatingIfUnknown(value + 1)); builder.setRepeatedField(field, i, mapEntryBuilder.build()); } // Verify that enum values have been successfully updated. TestMap message = builder.build(); for (Map.Entry<Integer, Integer> entry : message.getInt32ToEnumFieldValue().entrySet()) { assertEquals(data.get(entry.getKey()) + 1, entry.getValue().intValue()); } }
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, ""); } }