/** * Assigns all fields in {@link JsonNode} instance to a {@link Builder}. * * @param builder the builder to be populated * @param root the JSON object * @return the original builder, populated with any fields that were discovered */ public static Builder toProto(final Builder builder, final JsonNode root) { Descriptor type = builder.getDescriptorForType(); for (final FieldDescriptor fieldDesc : type.getFields()) { final String attrName = fieldDesc.getName(); final JsonNode node = root.get(attrName); if (node == null) { continue; } if (node.isNull()) { continue; } if (fieldDesc.isRepeated()) { final Iterator<JsonNode> iter = node.getElements(); while (iter.hasNext()) { builder.addRepeatedField(fieldDesc, toJavaObj(builder, fieldDesc, iter.next())); } } else { builder.setField(fieldDesc, toJavaObj(builder, fieldDesc, node)); } } return builder; }
private static void getRepeatedFieldNamesInternal(Descriptor d, Map<String, Set<String>> result) { Set<String> repeatedFields = Sets.newHashSet(); for (FieldDescriptor fd : d.getFields()) { if (fd.isRepeated()) { repeatedFields.add(javaCase(fd.getName())); } if (fd.getType() == FieldDescriptor.Type.MESSAGE) { getRepeatedFieldNamesInternal(fd.getMessageType(), result); } } if (!repeatedFields.isEmpty()) { result.put(javaCase(d.getName()), repeatedFields); } }
public static List<String> getMessageFieldNames( Descriptor descriptor, Map<String, String> fieldNameTranslations) { Function<FieldDescriptor, String> fieldTransformer = getFieldTransformerFor(fieldNameTranslations); return ListHelper.filter( Lists.transform(descriptor.getFields(), fieldTransformer), Predicates.<String>notNull()); }
/** Get a {@code DynamicMessage} representing the default instance of the given type. */ public static DynamicMessage getDefaultInstance(Descriptor type) { int oneofDeclCount = type.toProto().getOneofDeclCount(); FieldDescriptor[] oneofCases = new FieldDescriptor[oneofDeclCount]; return new DynamicMessage( type, FieldSet.<FieldDescriptor>emptySet(), oneofCases, UnknownFieldSet.getDefaultInstance()); }
public void writeTo(CodedOutputStream output) throws IOException { if (type.getOptions().getMessageSetWireFormat()) { fields.writeMessageSetTo(output); unknownFields.writeAsMessageSetTo(output); } else { fields.writeTo(output); unknownFields.writeTo(output); } }
/** * Recursively checks whether the specified class uses any Protocol Buffers fields that cannot be * deterministically encoded. * * @throws NonDeterministicException if the object cannot be encoded deterministically. */ static void verifyDeterministic(ProtoCoder<?> coder) throws NonDeterministicException { Class<? extends Message> message = coder.getMessageType(); ExtensionRegistry registry = coder.getExtensionRegistry(); Set<Descriptor> descriptors = getRecursiveDescriptorsForClass(message, registry); for (Descriptor d : descriptors) { for (FieldDescriptor fd : d.getFields()) { // If there is a transitively reachable Protocol Buffers map field, then this object cannot // be encoded deterministically. if (fd.isMapField()) { String reason = String.format( "Protocol Buffers message %s transitively includes Map field %s (from file %s)." + " Maps cannot be deterministically encoded.", message.getName(), fd.getFullName(), fd.getFile().getFullName()); throw new NonDeterministicException(coder, reason); } } } }
static boolean isInitialized(Descriptor type, FieldSet<FieldDescriptor> fields) { // Check that all required fields are present. for (final FieldDescriptor field : type.getFields()) { if (field.isRequired()) { if (!fields.hasField(field)) { return false; } } } // Check that embedded messages are initialized. return fields.isInitialized(); }
private static void recursivelyAddDescriptors( Descriptor message, Set<Descriptor> descriptors, ExtensionRegistry registry) { if (descriptors.contains(message)) { return; } descriptors.add(message); for (FieldDescriptor f : message.getFields()) { recursivelyAddDescriptors(f, descriptors, registry); } for (FieldDescriptor f : message.getExtensions()) { recursivelyAddDescriptors(f, descriptors, registry); } for (ExtensionInfo info : registry.getAllImmutableExtensionsByExtendedType(message.getFullName())) { recursivelyAddDescriptors(info.descriptor, descriptors, registry); } for (ExtensionInfo info : registry.getAllMutableExtensionsByExtendedType(message.getFullName())) { recursivelyAddDescriptors(info.descriptor, descriptors, registry); } }
public int getSerializedSize() { int size = memoizedSize; if (size != -1) return size; if (type.getOptions().getMessageSetWireFormat()) { size = fields.getMessageSetSerializedSize(); size += unknownFields.getSerializedSizeAsMessageSet(); } else { size = fields.getSerializedSize(); size += unknownFields.getSerializedSize(); } memoizedSize = size; return size; }
/** Construct a {@code Builder} for the given type. */ private Builder(Descriptor type) { this.type = type; this.fields = FieldSet.newFieldSet(); this.unknownFields = UnknownFieldSet.getDefaultInstance(); this.oneofCases = new FieldDescriptor[type.toProto().getOneofDeclCount()]; }
/** * Like {@link #mergeFrom(CodedInputStream, ExtensionRegistryLite)}, but parses a single field. * * <p>When {@code builder} is not null, the method will parse and merge the field into {@code * builder}. Otherwise, it will try to parse the field into {@code extensions}, when it's called * by the parsing constructor in generated classes. * * <p>Package-private because it is used by GeneratedMessage.ExtendableMessage. * * @param tag The tag, which should have already been read. * @return {@code true} unless the tag is an end-group tag. */ static boolean mergeFieldFrom( CodedInputStream input, UnknownFieldSet.Builder unknownFields, ExtensionRegistryLite extensionRegistry, Descriptor type, Message.Builder builder, FieldSet<FieldDescriptor> extensions, int tag) throws IOException { if (type.getOptions().getMessageSetWireFormat() && tag == WireFormat.MESSAGE_SET_ITEM_TAG) { mergeMessageSetExtensionFromCodedStream( input, unknownFields, extensionRegistry, type, builder, extensions); return true; } final int wireType = WireFormat.getTagWireType(tag); final int fieldNumber = WireFormat.getTagFieldNumber(tag); final FieldDescriptor field; Message defaultInstance = null; if (type.isExtensionNumber(fieldNumber)) { // extensionRegistry may be either ExtensionRegistry or // ExtensionRegistryLite. Since the type we are parsing is a full // message, only a full ExtensionRegistry could possibly contain // extensions of it. Otherwise we will treat the registry as if it // were empty. if (extensionRegistry instanceof ExtensionRegistry) { final ExtensionRegistry.ExtensionInfo extension = ((ExtensionRegistry) extensionRegistry).findExtensionByNumber(type, fieldNumber); if (extension == null) { field = null; } else { field = extension.descriptor; defaultInstance = extension.defaultInstance; if (defaultInstance == null && field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { throw new IllegalStateException( "Message-typed extension lacked default instance: " + field.getFullName()); } } } else { field = null; } } else if (builder != null) { field = type.findFieldByNumber(fieldNumber); } else { field = null; } boolean unknown = false; boolean packed = false; if (field == null) { unknown = true; // Unknown field. } else if (wireType == FieldSet.getWireFormatForFieldType(field.getLiteType(), false /* isPacked */)) { packed = false; } else if (field.isPackable() && wireType == FieldSet.getWireFormatForFieldType(field.getLiteType(), true /* isPacked */)) { packed = true; } else { unknown = true; // Unknown wire type. } if (unknown) { // Unknown field or wrong wire type. Skip. return unknownFields.mergeFieldFrom(tag, input); } if (packed) { final int length = input.readRawVarint32(); final int limit = input.pushLimit(length); if (field.getLiteType() == WireFormat.FieldType.ENUM) { while (input.getBytesUntilLimit() > 0) { final int rawValue = input.readEnum(); final Object value = field.getEnumType().findValueByNumber(rawValue); if (value == null) { // If the number isn't recognized as a valid value for this // enum, drop it (don't even add it to unknownFields). return true; } addRepeatedField(builder, extensions, field, value); } } else { while (input.getBytesUntilLimit() > 0) { final Object value = FieldSet.readPrimitiveField(input, field.getLiteType()); addRepeatedField(builder, extensions, field, value); } } input.popLimit(limit); } else { final Object value; switch (field.getType()) { case GROUP: { final Message.Builder subBuilder; if (defaultInstance != null) { subBuilder = defaultInstance.newBuilderForType(); } else { subBuilder = builder.newBuilderForField(field); } if (!field.isRepeated()) { mergeOriginalMessage(builder, extensions, field, subBuilder); } input.readGroup(field.getNumber(), subBuilder, extensionRegistry); value = subBuilder.buildPartial(); break; } case MESSAGE: { final Message.Builder subBuilder; if (defaultInstance != null) { subBuilder = defaultInstance.newBuilderForType(); } else { subBuilder = builder.newBuilderForField(field); } if (!field.isRepeated()) { mergeOriginalMessage(builder, extensions, field, subBuilder); } input.readMessage(subBuilder, extensionRegistry); value = subBuilder.buildPartial(); break; } case ENUM: final int rawValue = input.readEnum(); value = field.getEnumType().findValueByNumber(rawValue); // If the number isn't recognized as a valid value for this enum, // drop it. if (value == null) { unknownFields.mergeVarintField(fieldNumber, rawValue); return true; } break; default: value = FieldSet.readPrimitiveField(input, field.getLiteType()); break; } if (field.isRepeated()) { addRepeatedField(builder, extensions, field, value); } else { setField(builder, extensions, field, value); } } return true; }
/** * Like {@link #mergeFrom(CodedInputStream, UnknownFieldSet.Builder, ExtensionRegistryLite, * Message.Builder)}, but parses a single field. Package-private because it is used by * GeneratedMessage.ExtendableMessage. * * @param tag The tag, which should have already been read. * @return {@code true} unless the tag is an end-group tag. */ @SuppressWarnings("unchecked") static boolean mergeFieldFrom( final CodedInputStream input, final UnknownFieldSet.Builder unknownFields, final ExtensionRegistryLite extensionRegistry, final Message.Builder builder, final int tag) throws IOException { final Descriptor type = builder.getDescriptorForType(); if (type.getOptions().getMessageSetWireFormat() && tag == WireFormat.MESSAGE_SET_ITEM_TAG) { mergeMessageSetExtensionFromCodedStream(input, unknownFields, extensionRegistry, builder); return true; } final int wireType = WireFormat.getTagWireType(tag); final int fieldNumber = WireFormat.getTagFieldNumber(tag); final FieldDescriptor field; Message defaultInstance = null; if (type.isExtensionNumber(fieldNumber)) { // extensionRegistry may be either ExtensionRegistry or // ExtensionRegistryLite. Since the type we are parsing is a full // message, only a full ExtensionRegistry could possibly contain // extensions of it. Otherwise we will treat the registry as if it // were empty. if (extensionRegistry instanceof ExtensionRegistry) { final ExtensionRegistry.ExtensionInfo extension = ((ExtensionRegistry) extensionRegistry).findExtensionByNumber(type, fieldNumber); if (extension == null) { field = null; } else { field = extension.descriptor; defaultInstance = extension.defaultInstance; } } else { field = null; } } else { field = type.findFieldByNumber(fieldNumber); } if (field == null || wireType != FieldSet.getWireFormatForFieldType( field.getLiteType(), field.getOptions().getPacked())) { // Unknown field or wrong wire type. Skip. return unknownFields.mergeFieldFrom(tag, input); } if (field.getOptions().getPacked()) { final int length = input.readRawVarint32(); final int limit = input.pushLimit(length); if (field.getLiteType() == WireFormat.FieldType.ENUM) { while (input.getBytesUntilLimit() > 0) { final int rawValue = input.readEnum(); final Object value = field.getEnumType().findValueByNumber(rawValue); if (value == null) { // If the number isn't recognized as a valid value for this // enum, drop it (don't even add it to unknownFields). return true; } builder.addRepeatedField(field, value); } } else { while (input.getBytesUntilLimit() > 0) { final Object value = FieldSet.readPrimitiveField(input, field.getLiteType()); builder.addRepeatedField(field, value); } } input.popLimit(limit); } else { final Object value; switch (field.getType()) { case GROUP: { final Message.Builder subBuilder; if (defaultInstance != null) { subBuilder = defaultInstance.newBuilderForType(); } else { subBuilder = builder.newBuilderForField(field); } if (!field.isRepeated()) { subBuilder.mergeFrom((Message) builder.getField(field)); } input.readGroup(field.getNumber(), subBuilder, extensionRegistry); value = subBuilder.build(); break; } case MESSAGE: { final Message.Builder subBuilder; if (defaultInstance != null) { subBuilder = defaultInstance.newBuilderForType(); } else { subBuilder = builder.newBuilderForField(field); } if (!field.isRepeated()) { subBuilder.mergeFrom((Message) builder.getField(field)); } input.readMessage(subBuilder, extensionRegistry); value = subBuilder.build(); break; } case ENUM: final int rawValue = input.readEnum(); value = field.getEnumType().findValueByNumber(rawValue); // If the number isn't recognized as a valid value for this enum, // drop it. if (value == null) { unknownFields.mergeVarintField(fieldNumber, rawValue); return true; } break; default: value = FieldSet.readPrimitiveField(input, field.getLiteType()); break; } if (field.isRepeated()) { builder.addRepeatedField(field, value); } else { builder.setField(field, value); } } return true; }