Index: third_party/protobuf/java/src/main/java/com/google/protobuf/MessageReflection.java |
diff --git a/third_party/protobuf/java/src/main/java/com/google/protobuf/MessageReflection.java b/third_party/protobuf/java/src/main/java/com/google/protobuf/MessageReflection.java |
deleted file mode 100644 |
index de4bfd3ef3014d539b825c1d31e9668ac6703aad..0000000000000000000000000000000000000000 |
--- a/third_party/protobuf/java/src/main/java/com/google/protobuf/MessageReflection.java |
+++ /dev/null |
@@ -1,952 +0,0 @@ |
-// Protocol Buffers - Google's data interchange format |
-// Copyright 2008 Google Inc. All rights reserved. |
-// https://developers.google.com/protocol-buffers/ |
-// |
-// Redistribution and use in source and binary forms, with or without |
-// modification, are permitted provided that the following conditions are |
-// met: |
-// |
-// * Redistributions of source code must retain the above copyright |
-// notice, this list of conditions and the following disclaimer. |
-// * Redistributions in binary form must reproduce the above |
-// copyright notice, this list of conditions and the following disclaimer |
-// in the documentation and/or other materials provided with the |
-// distribution. |
-// * Neither the name of Google Inc. nor the names of its |
-// contributors may be used to endorse or promote products derived from |
-// this software without specific prior written permission. |
-// |
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
- |
-package com.google.protobuf; |
- |
-import com.google.protobuf.Descriptors.FieldDescriptor; |
- |
-import java.io.IOException; |
-import java.util.ArrayList; |
-import java.util.List; |
-import java.util.Map; |
-import java.util.TreeMap; |
- |
-/** |
- * Reflection utility methods shared by both mutable and immutable messages. |
- * |
- * @author liujisi@google.com (Pherl Liu) |
- */ |
-class MessageReflection { |
- |
- static void writeMessageTo( |
- Message message, |
- Map<FieldDescriptor, Object> fields, |
- CodedOutputStream output, |
- boolean alwaysWriteRequiredFields) |
- throws IOException { |
- final boolean isMessageSet = |
- message.getDescriptorForType().getOptions().getMessageSetWireFormat(); |
- if (alwaysWriteRequiredFields) { |
- fields = new TreeMap<FieldDescriptor, Object>(fields); |
- for (final FieldDescriptor field : |
- message.getDescriptorForType().getFields()) { |
- if (field.isRequired() && !fields.containsKey(field)) { |
- fields.put(field, message.getField(field)); |
- } |
- } |
- } |
- for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry : |
- fields.entrySet()) { |
- final Descriptors.FieldDescriptor field = entry.getKey(); |
- final Object value = entry.getValue(); |
- if (isMessageSet && field.isExtension() && |
- field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE && |
- !field.isRepeated()) { |
- output.writeMessageSetExtension(field.getNumber(), (Message) value); |
- } else { |
- FieldSet.writeField(field, value, output); |
- } |
- } |
- |
- final UnknownFieldSet unknownFields = message.getUnknownFields(); |
- if (isMessageSet) { |
- unknownFields.writeAsMessageSetTo(output); |
- } else { |
- unknownFields.writeTo(output); |
- } |
- } |
- |
- static int getSerializedSize( |
- Message message, |
- Map<FieldDescriptor, Object> fields) { |
- int size = 0; |
- final boolean isMessageSet = |
- message.getDescriptorForType().getOptions().getMessageSetWireFormat(); |
- |
- for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry : |
- fields.entrySet()) { |
- final Descriptors.FieldDescriptor field = entry.getKey(); |
- final Object value = entry.getValue(); |
- if (isMessageSet && field.isExtension() && |
- field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE && |
- !field.isRepeated()) { |
- size += CodedOutputStream.computeMessageSetExtensionSize( |
- field.getNumber(), (Message) value); |
- } else { |
- size += FieldSet.computeFieldSize(field, value); |
- } |
- } |
- |
- final UnknownFieldSet unknownFields = message.getUnknownFields(); |
- if (isMessageSet) { |
- size += unknownFields.getSerializedSizeAsMessageSet(); |
- } else { |
- size += unknownFields.getSerializedSize(); |
- } |
- return size; |
- } |
- |
- static String delimitWithCommas(List<String> parts) { |
- StringBuilder result = new StringBuilder(); |
- for (String part : parts) { |
- if (result.length() > 0) { |
- result.append(", "); |
- } |
- result.append(part); |
- } |
- return result.toString(); |
- } |
- |
- @SuppressWarnings("unchecked") |
- static boolean isInitialized(MessageOrBuilder message) { |
- // Check that all required fields are present. |
- for (final Descriptors.FieldDescriptor field : message |
- .getDescriptorForType() |
- .getFields()) { |
- if (field.isRequired()) { |
- if (!message.hasField(field)) { |
- return false; |
- } |
- } |
- } |
- |
- // Check that embedded messages are initialized. |
- for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry : |
- message.getAllFields().entrySet()) { |
- final Descriptors.FieldDescriptor field = entry.getKey(); |
- if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) { |
- if (field.isRepeated()) { |
- for (final Message element |
- : (List<Message>) entry.getValue()) { |
- if (!element.isInitialized()) { |
- return false; |
- } |
- } |
- } else { |
- if (!((Message) entry.getValue()).isInitialized()) { |
- return false; |
- } |
- } |
- } |
- } |
- |
- return true; |
- } |
- |
- private static String subMessagePrefix(final String prefix, |
- final Descriptors.FieldDescriptor field, |
- final int index) { |
- final StringBuilder result = new StringBuilder(prefix); |
- if (field.isExtension()) { |
- result.append('(') |
- .append(field.getFullName()) |
- .append(')'); |
- } else { |
- result.append(field.getName()); |
- } |
- if (index != -1) { |
- result.append('[') |
- .append(index) |
- .append(']'); |
- } |
- result.append('.'); |
- return result.toString(); |
- } |
- |
- private static void findMissingFields(final MessageOrBuilder message, |
- final String prefix, |
- final List<String> results) { |
- for (final Descriptors.FieldDescriptor field : |
- message.getDescriptorForType().getFields()) { |
- if (field.isRequired() && !message.hasField(field)) { |
- results.add(prefix + field.getName()); |
- } |
- } |
- |
- for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry : |
- message.getAllFields().entrySet()) { |
- final Descriptors.FieldDescriptor field = entry.getKey(); |
- final Object value = entry.getValue(); |
- |
- if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) { |
- if (field.isRepeated()) { |
- int i = 0; |
- for (final Object element : (List) value) { |
- findMissingFields((MessageOrBuilder) element, |
- subMessagePrefix(prefix, field, i++), |
- results); |
- } |
- } else { |
- if (message.hasField(field)) { |
- findMissingFields((MessageOrBuilder) value, |
- subMessagePrefix(prefix, field, -1), |
- results); |
- } |
- } |
- } |
- } |
- } |
- |
- /** |
- * Populates {@code this.missingFields} with the full "path" of each missing |
- * required field in the given message. |
- */ |
- static List<String> findMissingFields( |
- final MessageOrBuilder message) { |
- final List<String> results = new ArrayList<String>(); |
- findMissingFields(message, "", results); |
- return results; |
- } |
- |
- static interface MergeTarget { |
- enum ContainerType { |
- MESSAGE, EXTENSION_SET |
- } |
- |
- /** |
- * Returns the descriptor for the target. |
- */ |
- public Descriptors.Descriptor getDescriptorForType(); |
- |
- public ContainerType getContainerType(); |
- |
- public ExtensionRegistry.ExtensionInfo findExtensionByName( |
- ExtensionRegistry registry, String name); |
- |
- public ExtensionRegistry.ExtensionInfo findExtensionByNumber( |
- ExtensionRegistry registry, Descriptors.Descriptor containingType, |
- int fieldNumber); |
- |
- /** |
- * Obtains the value of the given field, or the default value if it is not |
- * set. For primitive fields, the boxed primitive value is returned. For |
- * enum fields, the EnumValueDescriptor for the value is returned. For |
- * embedded message fields, the sub-message is returned. For repeated |
- * fields, a java.util.List is returned. |
- */ |
- public Object getField(Descriptors.FieldDescriptor field); |
- |
- /** |
- * Returns true if the given field is set. This is exactly equivalent to |
- * calling the generated "has" accessor method corresponding to the field. |
- * |
- * @throws IllegalArgumentException The field is a repeated field, or {@code |
- * field.getContainingType() != getDescriptorForType()}. |
- */ |
- boolean hasField(Descriptors.FieldDescriptor field); |
- |
- /** |
- * Sets a field to the given value. The value must be of the correct type |
- * for this field, i.e. the same type that |
- * {@link Message#getField(Descriptors.FieldDescriptor)} |
- * would return. |
- */ |
- MergeTarget setField(Descriptors.FieldDescriptor field, Object value); |
- |
- /** |
- * Clears the field. This is exactly equivalent to calling the generated |
- * "clear" accessor method corresponding to the field. |
- */ |
- MergeTarget clearField(Descriptors.FieldDescriptor field); |
- |
- /** |
- * Sets an element of a repeated field to the given value. The value must |
- * be of the correct type for this field, i.e. the same type that {@link |
- * Message#getRepeatedField(Descriptors.FieldDescriptor, int)} would return. |
- * |
- * @throws IllegalArgumentException The field is not a repeated field, or |
- * {@code field.getContainingType() != |
- * getDescriptorForType()}. |
- */ |
- MergeTarget setRepeatedField(Descriptors.FieldDescriptor field, |
- int index, Object value); |
- |
- /** |
- * Like {@code setRepeatedField}, but appends the value as a new element. |
- * |
- * @throws IllegalArgumentException The field is not a repeated field, or |
- * {@code field.getContainingType() != |
- * getDescriptorForType()}. |
- */ |
- MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, |
- Object value); |
- |
- /** |
- * Returns true if the given oneof is set. |
- * |
- * @throws IllegalArgumentException if |
- * {@code oneof.getContainingType() != getDescriptorForType()}. |
- */ |
- boolean hasOneof(Descriptors.OneofDescriptor oneof); |
- |
- /** |
- * Clears the oneof. This is exactly equivalent to calling the generated |
- * "clear" accessor method corresponding to the oneof. |
- */ |
- MergeTarget clearOneof(Descriptors.OneofDescriptor oneof); |
- |
- /** |
- * Obtains the FieldDescriptor if the given oneof is set. Returns null |
- * if no field is set. |
- */ |
- Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof); |
- |
- /** |
- * Parse the input stream into a sub field group defined based on either |
- * FieldDescriptor or the default instance. |
- */ |
- Object parseGroup(CodedInputStream input, ExtensionRegistryLite registry, |
- Descriptors.FieldDescriptor descriptor, Message defaultInstance) |
- throws IOException; |
- |
- /** |
- * Parse the input stream into a sub field message defined based on either |
- * FieldDescriptor or the default instance. |
- */ |
- Object parseMessage(CodedInputStream input, ExtensionRegistryLite registry, |
- Descriptors.FieldDescriptor descriptor, Message defaultInstance) |
- throws IOException; |
- |
- /** |
- * Parse from a ByteString into a sub field message defined based on either |
- * FieldDescriptor or the default instance. There isn't a varint indicating |
- * the length of the message at the beginning of the input ByteString. |
- */ |
- Object parseMessageFromBytes( |
- ByteString bytes, ExtensionRegistryLite registry, |
- Descriptors.FieldDescriptor descriptor, Message defaultInstance) |
- throws IOException; |
- |
- /** |
- * Returns the UTF8 validation level for the field. |
- */ |
- WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor |
- descriptor); |
- |
- /** |
- * Returns a new merge target for a sub-field. When defaultInstance is |
- * provided, it indicates the descriptor is for an extension type, and |
- * implementations should create a new instance from the defaultInstance |
- * prototype directly. |
- */ |
- MergeTarget newMergeTargetForField( |
- Descriptors.FieldDescriptor descriptor, |
- Message defaultInstance); |
- |
- /** |
- * Finishes the merge and returns the underlying object. |
- */ |
- Object finish(); |
- } |
- |
- static class BuilderAdapter implements MergeTarget { |
- |
- private final Message.Builder builder; |
- |
- public Descriptors.Descriptor getDescriptorForType() { |
- return builder.getDescriptorForType(); |
- } |
- |
- public BuilderAdapter(Message.Builder builder) { |
- this.builder = builder; |
- } |
- |
- public Object getField(Descriptors.FieldDescriptor field) { |
- return builder.getField(field); |
- } |
- |
- @Override |
- public boolean hasField(Descriptors.FieldDescriptor field) { |
- return builder.hasField(field); |
- } |
- |
- public MergeTarget setField(Descriptors.FieldDescriptor field, |
- Object value) { |
- builder.setField(field, value); |
- return this; |
- } |
- |
- public MergeTarget clearField(Descriptors.FieldDescriptor field) { |
- builder.clearField(field); |
- return this; |
- } |
- |
- public MergeTarget setRepeatedField( |
- Descriptors.FieldDescriptor field, int index, Object value) { |
- builder.setRepeatedField(field, index, value); |
- return this; |
- } |
- |
- public MergeTarget addRepeatedField( |
- Descriptors.FieldDescriptor field, Object value) { |
- builder.addRepeatedField(field, value); |
- return this; |
- } |
- |
- @Override |
- public boolean hasOneof(Descriptors.OneofDescriptor oneof) { |
- return builder.hasOneof(oneof); |
- } |
- |
- @Override |
- public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) { |
- builder.clearOneof(oneof); |
- return this; |
- } |
- |
- @Override |
- public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) { |
- return builder.getOneofFieldDescriptor(oneof); |
- } |
- |
- public ContainerType getContainerType() { |
- return ContainerType.MESSAGE; |
- } |
- |
- public ExtensionRegistry.ExtensionInfo findExtensionByName( |
- ExtensionRegistry registry, String name) { |
- return registry.findImmutableExtensionByName(name); |
- } |
- |
- public ExtensionRegistry.ExtensionInfo findExtensionByNumber( |
- ExtensionRegistry registry, Descriptors.Descriptor containingType, |
- int fieldNumber) { |
- return registry.findImmutableExtensionByNumber(containingType, |
- fieldNumber); |
- } |
- |
- public Object parseGroup(CodedInputStream input, |
- ExtensionRegistryLite extensionRegistry, |
- Descriptors.FieldDescriptor field, Message defaultInstance) |
- throws IOException { |
- Message.Builder subBuilder; |
- // When default instance is not null. The field is an extension field. |
- if (defaultInstance != null) { |
- subBuilder = defaultInstance.newBuilderForType(); |
- } else { |
- subBuilder = builder.newBuilderForField(field); |
- } |
- if (!field.isRepeated()) { |
- Message originalMessage = (Message) getField(field); |
- if (originalMessage != null) { |
- subBuilder.mergeFrom(originalMessage); |
- } |
- } |
- input.readGroup(field.getNumber(), subBuilder, extensionRegistry); |
- return subBuilder.buildPartial(); |
- } |
- |
- public Object parseMessage(CodedInputStream input, |
- ExtensionRegistryLite extensionRegistry, |
- Descriptors.FieldDescriptor field, Message defaultInstance) |
- throws IOException { |
- Message.Builder subBuilder; |
- // When default instance is not null. The field is an extension field. |
- if (defaultInstance != null) { |
- subBuilder = defaultInstance.newBuilderForType(); |
- } else { |
- subBuilder = builder.newBuilderForField(field); |
- } |
- if (!field.isRepeated()) { |
- Message originalMessage = (Message) getField(field); |
- if (originalMessage != null) { |
- subBuilder.mergeFrom(originalMessage); |
- } |
- } |
- input.readMessage(subBuilder, extensionRegistry); |
- return subBuilder.buildPartial(); |
- } |
- |
- public Object parseMessageFromBytes(ByteString bytes, |
- ExtensionRegistryLite extensionRegistry, |
- Descriptors.FieldDescriptor field, Message defaultInstance) |
- throws IOException { |
- Message.Builder subBuilder; |
- // When default instance is not null. The field is an extension field. |
- if (defaultInstance != null) { |
- subBuilder = defaultInstance.newBuilderForType(); |
- } else { |
- subBuilder = builder.newBuilderForField(field); |
- } |
- if (!field.isRepeated()) { |
- Message originalMessage = (Message) getField(field); |
- if (originalMessage != null) { |
- subBuilder.mergeFrom(originalMessage); |
- } |
- } |
- subBuilder.mergeFrom(bytes, extensionRegistry); |
- return subBuilder.buildPartial(); |
- } |
- |
- public MergeTarget newMergeTargetForField(Descriptors.FieldDescriptor field, |
- Message defaultInstance) { |
- if (defaultInstance != null) { |
- return new BuilderAdapter( |
- defaultInstance.newBuilderForType()); |
- } else { |
- return new BuilderAdapter(builder.newBuilderForField(field)); |
- } |
- } |
- |
- public WireFormat.Utf8Validation |
- getUtf8Validation(Descriptors.FieldDescriptor descriptor) { |
- if (descriptor.needsUtf8Check()) { |
- return WireFormat.Utf8Validation.STRICT; |
- } |
- // TODO(liujisi): support lazy strings for repeated fields. |
- if (!descriptor.isRepeated() |
- && builder instanceof GeneratedMessage.Builder) { |
- return WireFormat.Utf8Validation.LAZY; |
- } |
- return WireFormat.Utf8Validation.LOOSE; |
- } |
- |
- public Object finish() { |
- return builder.buildPartial(); |
- } |
- } |
- |
- |
- static class ExtensionAdapter implements MergeTarget { |
- |
- private final FieldSet<Descriptors.FieldDescriptor> extensions; |
- |
- ExtensionAdapter(FieldSet<Descriptors.FieldDescriptor> extensions) { |
- this.extensions = extensions; |
- } |
- |
- public Descriptors.Descriptor getDescriptorForType() { |
- throw new UnsupportedOperationException( |
- "getDescriptorForType() called on FieldSet object"); |
- } |
- |
- public Object getField(Descriptors.FieldDescriptor field) { |
- return extensions.getField(field); |
- } |
- |
- public boolean hasField(Descriptors.FieldDescriptor field) { |
- return extensions.hasField(field); |
- } |
- |
- public MergeTarget setField(Descriptors.FieldDescriptor field, |
- Object value) { |
- extensions.setField(field, value); |
- return this; |
- } |
- |
- public MergeTarget clearField(Descriptors.FieldDescriptor field) { |
- extensions.clearField(field); |
- return this; |
- } |
- |
- public MergeTarget setRepeatedField( |
- Descriptors.FieldDescriptor field, int index, Object value) { |
- extensions.setRepeatedField(field, index, value); |
- return this; |
- } |
- |
- public MergeTarget addRepeatedField( |
- Descriptors.FieldDescriptor field, Object value) { |
- extensions.addRepeatedField(field, value); |
- return this; |
- } |
- |
- @Override |
- public boolean hasOneof(Descriptors.OneofDescriptor oneof) { |
- return false; |
- } |
- |
- @Override |
- public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) { |
- // Nothing to clear. |
- return this; |
- } |
- |
- @Override |
- public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) { |
- return null; |
- } |
- |
- public ContainerType getContainerType() { |
- return ContainerType.EXTENSION_SET; |
- } |
- |
- public ExtensionRegistry.ExtensionInfo findExtensionByName( |
- ExtensionRegistry registry, String name) { |
- return registry.findImmutableExtensionByName(name); |
- } |
- |
- public ExtensionRegistry.ExtensionInfo findExtensionByNumber( |
- ExtensionRegistry registry, Descriptors.Descriptor containingType, |
- int fieldNumber) { |
- return registry.findImmutableExtensionByNumber(containingType, |
- fieldNumber); |
- } |
- |
- public Object parseGroup(CodedInputStream input, |
- ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, |
- Message defaultInstance) throws IOException { |
- Message.Builder subBuilder = |
- defaultInstance.newBuilderForType(); |
- if (!field.isRepeated()) { |
- Message originalMessage = (Message) getField(field); |
- if (originalMessage != null) { |
- subBuilder.mergeFrom(originalMessage); |
- } |
- } |
- input.readGroup(field.getNumber(), subBuilder, registry); |
- return subBuilder.buildPartial(); |
- } |
- |
- public Object parseMessage(CodedInputStream input, |
- ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, |
- Message defaultInstance) throws IOException { |
- Message.Builder subBuilder = |
- defaultInstance.newBuilderForType(); |
- if (!field.isRepeated()) { |
- Message originalMessage = (Message) getField(field); |
- if (originalMessage != null) { |
- subBuilder.mergeFrom(originalMessage); |
- } |
- } |
- input.readMessage(subBuilder, registry); |
- return subBuilder.buildPartial(); |
- } |
- |
- public Object parseMessageFromBytes(ByteString bytes, |
- ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, |
- Message defaultInstance) throws IOException { |
- Message.Builder subBuilder = defaultInstance.newBuilderForType(); |
- if (!field.isRepeated()) { |
- Message originalMessage = (Message) getField(field); |
- if (originalMessage != null) { |
- subBuilder.mergeFrom(originalMessage); |
- } |
- } |
- subBuilder.mergeFrom(bytes, registry); |
- return subBuilder.buildPartial(); |
- } |
- |
- public MergeTarget newMergeTargetForField( |
- Descriptors.FieldDescriptor descriptor, Message defaultInstance) { |
- throw new UnsupportedOperationException( |
- "newMergeTargetForField() called on FieldSet object"); |
- } |
- |
- public WireFormat.Utf8Validation |
- getUtf8Validation(Descriptors.FieldDescriptor descriptor) { |
- if (descriptor.needsUtf8Check()) { |
- return WireFormat.Utf8Validation.STRICT; |
- } |
- // TODO(liujisi): support lazy strings for ExtesnsionSet. |
- return WireFormat.Utf8Validation.LOOSE; |
- } |
- |
- public Object finish() { |
- throw new UnsupportedOperationException( |
- "finish() called on FieldSet object"); |
- } |
- } |
- |
- /** |
- * Parses a single field into MergeTarget. The target can be Message.Builder, |
- * FieldSet or MutableMessage. |
- * |
- * 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, |
- Descriptors.Descriptor type, |
- MergeTarget target, |
- int tag) throws IOException { |
- if (type.getOptions().getMessageSetWireFormat() && |
- tag == WireFormat.MESSAGE_SET_ITEM_TAG) { |
- mergeMessageSetExtensionFromCodedStream( |
- input, unknownFields, extensionRegistry, type, target); |
- return true; |
- } |
- |
- final int wireType = WireFormat.getTagWireType(tag); |
- final int fieldNumber = WireFormat.getTagFieldNumber(tag); |
- |
- final Descriptors.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 = |
- target.findExtensionByNumber((ExtensionRegistry) extensionRegistry, |
- type, fieldNumber); |
- if (extension == null) { |
- field = null; |
- } else { |
- field = extension.descriptor; |
- defaultInstance = extension.defaultInstance; |
- if (defaultInstance == null && |
- field.getJavaType() |
- == Descriptors.FieldDescriptor.JavaType.MESSAGE) { |
- throw new IllegalStateException( |
- "Message-typed extension lacked default instance: " + |
- field.getFullName()); |
- } |
- } |
- } else { |
- field = null; |
- } |
- } else if (target.getContainerType() == MergeTarget.ContainerType.MESSAGE) { |
- 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(); |
- if (field.getFile().supportsUnknownEnumValue()) { |
- target.addRepeatedField(field, |
- field.getEnumType().findValueByNumberCreatingIfUnknown(rawValue)); |
- } else { |
- 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; |
- } |
- target.addRepeatedField(field, value); |
- } |
- } |
- } else { |
- while (input.getBytesUntilLimit() > 0) { |
- final Object value = WireFormat.readPrimitiveField( |
- input, field.getLiteType(), target.getUtf8Validation(field)); |
- target.addRepeatedField(field, value); |
- } |
- } |
- input.popLimit(limit); |
- } else { |
- final Object value; |
- switch (field.getType()) { |
- case GROUP: { |
- value = target |
- .parseGroup(input, extensionRegistry, field, defaultInstance); |
- break; |
- } |
- case MESSAGE: { |
- value = target |
- .parseMessage(input, extensionRegistry, field, defaultInstance); |
- break; |
- } |
- case ENUM: |
- final int rawValue = input.readEnum(); |
- if (field.getFile().supportsUnknownEnumValue()) { |
- value = field.getEnumType().findValueByNumberCreatingIfUnknown(rawValue); |
- } else { |
- 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 = WireFormat.readPrimitiveField( |
- input, field.getLiteType(), target.getUtf8Validation(field)); |
- break; |
- } |
- |
- if (field.isRepeated()) { |
- target.addRepeatedField(field, value); |
- } else { |
- target.setField(field, value); |
- } |
- } |
- |
- return true; |
- } |
- |
- /** |
- * Called by {@code #mergeFieldFrom()} to parse a MessageSet extension into |
- * MergeTarget. |
- */ |
- private static void mergeMessageSetExtensionFromCodedStream( |
- CodedInputStream input, |
- UnknownFieldSet.Builder unknownFields, |
- ExtensionRegistryLite extensionRegistry, |
- Descriptors.Descriptor type, |
- MergeTarget target) throws IOException { |
- |
- // The wire format for MessageSet is: |
- // message MessageSet { |
- // repeated group Item = 1 { |
- // required int32 typeId = 2; |
- // required bytes message = 3; |
- // } |
- // } |
- // "typeId" is the extension's field number. The extension can only be |
- // a message type, where "message" contains the encoded bytes of that |
- // message. |
- // |
- // In practice, we will probably never see a MessageSet item in which |
- // the message appears before the type ID, or where either field does not |
- // appear exactly once. However, in theory such cases are valid, so we |
- // should be prepared to accept them. |
- |
- int typeId = 0; |
- ByteString rawBytes = null; // If we encounter "message" before "typeId" |
- ExtensionRegistry.ExtensionInfo extension = null; |
- |
- // Read bytes from input, if we get it's type first then parse it eagerly, |
- // otherwise we store the raw bytes in a local variable. |
- while (true) { |
- final int tag = input.readTag(); |
- if (tag == 0) { |
- break; |
- } |
- |
- if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) { |
- typeId = input.readUInt32(); |
- if (typeId != 0) { |
- // 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) { |
- extension = target.findExtensionByNumber( |
- (ExtensionRegistry) extensionRegistry, type, typeId); |
- } |
- } |
- |
- } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) { |
- if (typeId != 0) { |
- if (extension != null && |
- ExtensionRegistryLite.isEagerlyParseMessageSets()) { |
- // We already know the type, so we can parse directly from the |
- // input with no copying. Hooray! |
- eagerlyMergeMessageSetExtension( |
- input, extension, extensionRegistry, target); |
- rawBytes = null; |
- continue; |
- } |
- } |
- // We haven't seen a type ID yet or we want parse message lazily. |
- rawBytes = input.readBytes(); |
- |
- } else { // Unknown tag. Skip it. |
- if (!input.skipField(tag)) { |
- break; // End of group |
- } |
- } |
- } |
- input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG); |
- |
- // Process the raw bytes. |
- if (rawBytes != null && typeId != 0) { // Zero is not a valid type ID. |
- if (extension != null) { // We known the type |
- mergeMessageSetExtensionFromBytes( |
- rawBytes, extension, extensionRegistry, target); |
- } else { // We don't know how to parse this. Ignore it. |
- if (rawBytes != null) { |
- unknownFields.mergeField(typeId, UnknownFieldSet.Field.newBuilder() |
- .addLengthDelimited(rawBytes).build()); |
- } |
- } |
- } |
- } |
- |
- private static void mergeMessageSetExtensionFromBytes( |
- ByteString rawBytes, |
- ExtensionRegistry.ExtensionInfo extension, |
- ExtensionRegistryLite extensionRegistry, |
- MergeTarget target) throws IOException { |
- |
- Descriptors.FieldDescriptor field = extension.descriptor; |
- boolean hasOriginalValue = target.hasField(field); |
- |
- if (hasOriginalValue || ExtensionRegistryLite.isEagerlyParseMessageSets()) { |
- // If the field already exists, we just parse the field. |
- Object value = target.parseMessageFromBytes( |
- rawBytes, extensionRegistry,field, extension.defaultInstance); |
- target.setField(field, value); |
- } else { |
- // Use LazyField to load MessageSet lazily. |
- LazyField lazyField = new LazyField( |
- extension.defaultInstance, extensionRegistry, rawBytes); |
- target.setField(field, lazyField); |
- } |
- } |
- |
- private static void eagerlyMergeMessageSetExtension( |
- CodedInputStream input, |
- ExtensionRegistry.ExtensionInfo extension, |
- ExtensionRegistryLite extensionRegistry, |
- MergeTarget target) throws IOException { |
- Descriptors.FieldDescriptor field = extension.descriptor; |
- Object value = target.parseMessage(input, extensionRegistry, field, |
- extension.defaultInstance); |
- target.setField(field, value); |
- } |
-} |