private static void eagerlyMergeMessageSetExtension( CodedInputStream input, ExtensionRegistry.ExtensionInfo extension, ExtensionRegistryLite extensionRegistry, Message.Builder builder, FieldSet<FieldDescriptor> extensions) throws IOException { FieldDescriptor field = extension.descriptor; Message value = null; if (hasOriginalMessage(builder, extensions, field)) { Message originalMessage = getOriginalMessage(builder, extensions, field); Message.Builder subBuilder = originalMessage.toBuilder(); input.readMessage(subBuilder, extensionRegistry); value = subBuilder.buildPartial(); } else { value = input.readMessage(extension.defaultInstance.getParserForType(), extensionRegistry); } if (builder != null) { builder.setField(field, value); } else { extensions.setField(field, value); } }
/** * Clones the FieldSet. The returned FieldSet will be mutable even if the original FieldSet was * immutable. * * @return the newly cloned FieldSet */ @Override public FieldSet<FieldDescriptorType> clone() { // We can't just call fields.clone because List objects in the map // should not be shared. FieldSet<FieldDescriptorType> clone = FieldSet.newFieldSet(); for (int i = 0; i < fields.getNumArrayEntries(); i++) { Map.Entry<FieldDescriptorType, Object> entry = fields.getArrayEntryAt(i); FieldDescriptorType descriptor = entry.getKey(); clone.setField(descriptor, entry.getValue()); } for (Map.Entry<FieldDescriptorType, Object> entry : fields.getOverflowEntries()) { FieldDescriptorType descriptor = entry.getKey(); clone.setField(descriptor, entry.getValue()); } return clone; }
/** helper method to handle {@code builder} and {@code extensions}. */ private static void setField( Message.Builder builder, FieldSet<FieldDescriptor> extensions, FieldDescriptor field, Object value) { if (builder != null) { builder.setField(field, value); } else { extensions.setField(field, value); } }
public Builder setField(FieldDescriptor field, Object value) { verifyContainingType(field); ensureIsMutable(); if (field.getType() == FieldDescriptor.Type.ENUM) { verifyEnumType(field, value); } OneofDescriptor oneofDescriptor = field.getContainingOneof(); if (oneofDescriptor != null) { int index = oneofDescriptor.getIndex(); FieldDescriptor oldField = oneofCases[index]; if ((oldField != null) && (oldField != field)) { fields.clearField(oldField); } oneofCases[index] = field; } fields.setField(field, value); return this; }
private static void mergeMessageSetExtensionFromBytes( ByteString rawBytes, ExtensionRegistry.ExtensionInfo extension, ExtensionRegistryLite extensionRegistry, Message.Builder builder, FieldSet<FieldDescriptor> extensions) throws IOException { FieldDescriptor field = extension.descriptor; boolean hasOriginalValue = hasOriginalMessage(builder, extensions, field); if (hasOriginalValue || ExtensionRegistryLite.isEagerlyParseMessageSets()) { // If the field already exists, we just parse the field. Message value = null; if (hasOriginalValue) { Message originalMessage = getOriginalMessage(builder, extensions, field); Message.Builder subBuilder = originalMessage.toBuilder(); subBuilder.mergeFrom(rawBytes, extensionRegistry); value = subBuilder.buildPartial(); } else { value = extension .defaultInstance .getParserForType() .parsePartialFrom(rawBytes, extensionRegistry); } setField(builder, extensions, field, value); } else { // Use LazyField to load MessageSet lazily. LazyField lazyField = new LazyField(extension.defaultInstance, extensionRegistry, rawBytes); if (builder != null) { // TODO(xiangl): it looks like this method can only be invoked by // ExtendableBuilder, but I'm not sure. So I double check the type of // builder here. It may be useless and need more investigation. if (builder instanceof ExtendableBuilder) { builder.setField(field, lazyField); } else { builder.setField(field, lazyField.getValue()); } } else { extensions.setField(field, lazyField); } } }
@Override public Builder setField(FieldDescriptor field, Object value) { verifyContainingType(field); fields.setField(field, value); return this; }
/** * Called by subclasses to parse an unknown field or an extension. * * @return {@code true} unless the tag is an end-group tag. */ @Override protected boolean parseUnknownField( final CodedInputStream input, final ExtensionRegistryLite extensionRegistry, final int tag) throws IOException { final FieldSet<ExtensionDescriptor> extensions = ((ExtendableMessage) internalGetResult()).extensions; final int wireType = WireFormat.getTagWireType(tag); final int fieldNumber = WireFormat.getTagFieldNumber(tag); final GeneratedExtension<MessageType, ?> extension = extensionRegistry.findLiteExtensionByNumber(getDefaultInstanceForType(), fieldNumber); boolean unknown = false; boolean packed = false; if (extension == null) { unknown = true; // Unknown field. } else if (wireType == FieldSet.getWireFormatForFieldType( extension.descriptor.getLiteType(), false /* isPacked */)) { packed = false; // Normal, unpacked value. } else if (extension.descriptor.isRepeated && extension.descriptor.type.isPackable() && wireType == FieldSet.getWireFormatForFieldType( extension.descriptor.getLiteType(), true /* isPacked */)) { packed = true; // Packed value. } else { unknown = true; // Wrong wire type. } if (unknown) { // Unknown field or wrong wire type. Skip. return input.skipField(tag); } if (packed) { final int length = input.readRawVarint32(); final int limit = input.pushLimit(length); if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) { while (input.getBytesUntilLimit() > 0) { final int rawValue = input.readEnum(); final Object value = extension.descriptor.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; } extensions.addRepeatedField(extension.descriptor, value); } } else { while (input.getBytesUntilLimit() > 0) { final Object value = FieldSet.readPrimitiveField(input, extension.descriptor.getLiteType()); extensions.addRepeatedField(extension.descriptor, value); } } input.popLimit(limit); } else { final Object value; switch (extension.descriptor.getLiteJavaType()) { case MESSAGE: { MessageLite.Builder subBuilder = null; if (!extension.descriptor.isRepeated()) { MessageLite existingValue = (MessageLite) extensions.getField(extension.descriptor); if (existingValue != null) { subBuilder = existingValue.toBuilder(); } } if (subBuilder == null) { subBuilder = extension.messageDefaultInstance.newBuilderForType(); } if (extension.descriptor.getLiteType() == WireFormat.FieldType.GROUP) { input.readGroup(extension.getNumber(), subBuilder, extensionRegistry); } else { input.readMessage(subBuilder, extensionRegistry); } value = subBuilder.build(); break; } case ENUM: final int rawValue = input.readEnum(); value = extension.descriptor.getEnumType().findValueByNumber(rawValue); // If the number isn't recognized as a valid value for this enum, // drop it. if (value == null) { return true; } break; default: value = FieldSet.readPrimitiveField(input, extension.descriptor.getLiteType()); break; } if (extension.descriptor.isRepeated()) { extensions.addRepeatedField(extension.descriptor, value); } else { extensions.setField(extension.descriptor, value); } } return true; }