| Index: third_party/protobuf/java/src/main/java/com/google/protobuf/AbstractMessage.java
|
| diff --git a/third_party/protobuf/java/src/main/java/com/google/protobuf/AbstractMessage.java b/third_party/protobuf/java/src/main/java/com/google/protobuf/AbstractMessage.java
|
| deleted file mode 100644
|
| index f4d115de253faa617c1eb44974881f736c928979..0000000000000000000000000000000000000000
|
| --- a/third_party/protobuf/java/src/main/java/com/google/protobuf/AbstractMessage.java
|
| +++ /dev/null
|
| @@ -1,930 +0,0 @@
|
| -// Protocol Buffers - Google's data interchange format
|
| -// Copyright 2008 Google Inc. All rights reserved.
|
| -// http://code.google.com/p/protobuf/
|
| -//
|
| -// 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.Descriptor;
|
| -import com.google.protobuf.Descriptors.FieldDescriptor;
|
| -import com.google.protobuf.GeneratedMessage.ExtendableBuilder;
|
| -import com.google.protobuf.Internal.EnumLite;
|
| -
|
| -import java.io.IOException;
|
| -import java.io.InputStream;
|
| -import java.util.ArrayList;
|
| -import java.util.List;
|
| -import java.util.Map;
|
| -
|
| -/**
|
| - * A partial implementation of the {@link Message} interface which implements
|
| - * as many methods of that interface as possible in terms of other methods.
|
| - *
|
| - * @author kenton@google.com Kenton Varda
|
| - */
|
| -public abstract class AbstractMessage extends AbstractMessageLite
|
| - implements Message {
|
| - @SuppressWarnings("unchecked")
|
| - public boolean isInitialized() {
|
| - // Check that all required fields are present.
|
| - for (final FieldDescriptor field : getDescriptorForType().getFields()) {
|
| - if (field.isRequired()) {
|
| - if (!hasField(field)) {
|
| - return false;
|
| - }
|
| - }
|
| - }
|
| -
|
| - // Check that embedded messages are initialized.
|
| - for (final Map.Entry<FieldDescriptor, Object> entry :
|
| - getAllFields().entrySet()) {
|
| - final FieldDescriptor field = entry.getKey();
|
| - if (field.getJavaType() == 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;
|
| - }
|
| -
|
| - public List<String> findInitializationErrors() {
|
| - return Builder.findMissingFields(this);
|
| - }
|
| -
|
| - public String getInitializationErrorString() {
|
| - return delimitWithCommas(findInitializationErrors());
|
| - }
|
| -
|
| - private 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();
|
| - }
|
| -
|
| - @Override
|
| - public final String toString() {
|
| - return TextFormat.printToString(this);
|
| - }
|
| -
|
| - public void writeTo(final CodedOutputStream output) throws IOException {
|
| - final boolean isMessageSet =
|
| - getDescriptorForType().getOptions().getMessageSetWireFormat();
|
| -
|
| - for (final Map.Entry<FieldDescriptor, Object> entry :
|
| - getAllFields().entrySet()) {
|
| - final FieldDescriptor field = entry.getKey();
|
| - final Object value = entry.getValue();
|
| - if (isMessageSet && field.isExtension() &&
|
| - field.getType() == FieldDescriptor.Type.MESSAGE &&
|
| - !field.isRepeated()) {
|
| - output.writeMessageSetExtension(field.getNumber(), (Message) value);
|
| - } else {
|
| - FieldSet.writeField(field, value, output);
|
| - }
|
| - }
|
| -
|
| - final UnknownFieldSet unknownFields = getUnknownFields();
|
| - if (isMessageSet) {
|
| - unknownFields.writeAsMessageSetTo(output);
|
| - } else {
|
| - unknownFields.writeTo(output);
|
| - }
|
| - }
|
| -
|
| - private int memoizedSize = -1;
|
| -
|
| - public int getSerializedSize() {
|
| - int size = memoizedSize;
|
| - if (size != -1) {
|
| - return size;
|
| - }
|
| -
|
| - size = 0;
|
| - final boolean isMessageSet =
|
| - getDescriptorForType().getOptions().getMessageSetWireFormat();
|
| -
|
| - for (final Map.Entry<FieldDescriptor, Object> entry :
|
| - getAllFields().entrySet()) {
|
| - final FieldDescriptor field = entry.getKey();
|
| - final Object value = entry.getValue();
|
| - if (isMessageSet && field.isExtension() &&
|
| - field.getType() == FieldDescriptor.Type.MESSAGE &&
|
| - !field.isRepeated()) {
|
| - size += CodedOutputStream.computeMessageSetExtensionSize(
|
| - field.getNumber(), (Message) value);
|
| - } else {
|
| - size += FieldSet.computeFieldSize(field, value);
|
| - }
|
| - }
|
| -
|
| - final UnknownFieldSet unknownFields = getUnknownFields();
|
| - if (isMessageSet) {
|
| - size += unknownFields.getSerializedSizeAsMessageSet();
|
| - } else {
|
| - size += unknownFields.getSerializedSize();
|
| - }
|
| -
|
| - memoizedSize = size;
|
| - return size;
|
| - }
|
| -
|
| - @Override
|
| - public boolean equals(final Object other) {
|
| - if (other == this) {
|
| - return true;
|
| - }
|
| - if (!(other instanceof Message)) {
|
| - return false;
|
| - }
|
| - final Message otherMessage = (Message) other;
|
| - if (getDescriptorForType() != otherMessage.getDescriptorForType()) {
|
| - return false;
|
| - }
|
| - return getAllFields().equals(otherMessage.getAllFields()) &&
|
| - getUnknownFields().equals(otherMessage.getUnknownFields());
|
| - }
|
| -
|
| - @Override
|
| - public int hashCode() {
|
| - int hash = 41;
|
| - hash = (19 * hash) + getDescriptorForType().hashCode();
|
| - hash = hashFields(hash, getAllFields());
|
| - hash = (29 * hash) + getUnknownFields().hashCode();
|
| - return hash;
|
| - }
|
| -
|
| - /** Get a hash code for given fields and values, using the given seed. */
|
| - @SuppressWarnings("unchecked")
|
| - protected int hashFields(int hash, Map<FieldDescriptor, Object> map) {
|
| - for (Map.Entry<FieldDescriptor, Object> entry : map.entrySet()) {
|
| - FieldDescriptor field = entry.getKey();
|
| - Object value = entry.getValue();
|
| - hash = (37 * hash) + field.getNumber();
|
| - if (field.getType() != FieldDescriptor.Type.ENUM){
|
| - hash = (53 * hash) + value.hashCode();
|
| - } else if (field.isRepeated()) {
|
| - List<? extends EnumLite> list = (List<? extends EnumLite>) value;
|
| - hash = (53 * hash) + hashEnumList(list);
|
| - } else {
|
| - hash = (53 * hash) + hashEnum((EnumLite) value);
|
| - }
|
| - }
|
| - return hash;
|
| - }
|
| -
|
| - /**
|
| - * Helper method for implementing {@link Message#hashCode()}.
|
| - * @see Boolean#hashCode()
|
| - */
|
| - protected static int hashLong(long n) {
|
| - return (int) (n ^ (n >>> 32));
|
| - }
|
| -
|
| - /**
|
| - * Helper method for implementing {@link Message#hashCode()}.
|
| - * @see Boolean#hashCode()
|
| - */
|
| - protected static int hashBoolean(boolean b) {
|
| - return b ? 1231 : 1237;
|
| - }
|
| -
|
| - /**
|
| - * Package private helper method for AbstractParser to create
|
| - * UninitializedMessageException with missing field information.
|
| - */
|
| - @Override
|
| - UninitializedMessageException newUninitializedMessageException() {
|
| - return Builder.newUninitializedMessageException(this);
|
| - }
|
| -
|
| - /**
|
| - * Helper method for implementing {@link Message#hashCode()}.
|
| - * <p>
|
| - * This is needed because {@link java.lang.Enum#hashCode()} is final, but we
|
| - * need to use the field number as the hash code to ensure compatibility
|
| - * between statically and dynamically generated enum objects.
|
| - */
|
| - protected static int hashEnum(EnumLite e) {
|
| - return e.getNumber();
|
| - }
|
| -
|
| - /** Helper method for implementing {@link Message#hashCode()}. */
|
| - protected static int hashEnumList(List<? extends EnumLite> list) {
|
| - int hash = 1;
|
| - for (EnumLite e : list) {
|
| - hash = 31 * hash + hashEnum(e);
|
| - }
|
| - return hash;
|
| - }
|
| -
|
| - // =================================================================
|
| -
|
| - /**
|
| - * A partial implementation of the {@link Message.Builder} interface which
|
| - * implements as many methods of that interface as possible in terms of
|
| - * other methods.
|
| - */
|
| - @SuppressWarnings("unchecked")
|
| - public static abstract class Builder<BuilderType extends Builder>
|
| - extends AbstractMessageLite.Builder<BuilderType>
|
| - implements Message.Builder {
|
| - // The compiler produces an error if this is not declared explicitly.
|
| - @Override
|
| - public abstract BuilderType clone();
|
| -
|
| - public BuilderType clear() {
|
| - for (final Map.Entry<FieldDescriptor, Object> entry :
|
| - getAllFields().entrySet()) {
|
| - clearField(entry.getKey());
|
| - }
|
| - return (BuilderType) this;
|
| - }
|
| -
|
| - public List<String> findInitializationErrors() {
|
| - return findMissingFields(this);
|
| - }
|
| -
|
| - public String getInitializationErrorString() {
|
| - return delimitWithCommas(findInitializationErrors());
|
| - }
|
| -
|
| - public BuilderType mergeFrom(final Message other) {
|
| - if (other.getDescriptorForType() != getDescriptorForType()) {
|
| - throw new IllegalArgumentException(
|
| - "mergeFrom(Message) can only merge messages of the same type.");
|
| - }
|
| -
|
| - // Note: We don't attempt to verify that other's fields have valid
|
| - // types. Doing so would be a losing battle. We'd have to verify
|
| - // all sub-messages as well, and we'd have to make copies of all of
|
| - // them to insure that they don't change after verification (since
|
| - // the Message interface itself cannot enforce immutability of
|
| - // implementations).
|
| - // TODO(kenton): Provide a function somewhere called makeDeepCopy()
|
| - // which allows people to make secure deep copies of messages.
|
| -
|
| - for (final Map.Entry<FieldDescriptor, Object> entry :
|
| - other.getAllFields().entrySet()) {
|
| - final FieldDescriptor field = entry.getKey();
|
| - if (field.isRepeated()) {
|
| - for (final Object element : (List)entry.getValue()) {
|
| - addRepeatedField(field, element);
|
| - }
|
| - } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
|
| - final Message existingValue = (Message)getField(field);
|
| - if (existingValue == existingValue.getDefaultInstanceForType()) {
|
| - setField(field, entry.getValue());
|
| - } else {
|
| - setField(field,
|
| - existingValue.newBuilderForType()
|
| - .mergeFrom(existingValue)
|
| - .mergeFrom((Message)entry.getValue())
|
| - .build());
|
| - }
|
| - } else {
|
| - setField(field, entry.getValue());
|
| - }
|
| - }
|
| -
|
| - mergeUnknownFields(other.getUnknownFields());
|
| -
|
| - return (BuilderType) this;
|
| - }
|
| -
|
| - @Override
|
| - public BuilderType mergeFrom(final CodedInputStream input)
|
| - throws IOException {
|
| - return mergeFrom(input, ExtensionRegistry.getEmptyRegistry());
|
| - }
|
| -
|
| - @Override
|
| - public BuilderType mergeFrom(
|
| - final CodedInputStream input,
|
| - final ExtensionRegistryLite extensionRegistry)
|
| - throws IOException {
|
| - final UnknownFieldSet.Builder unknownFields =
|
| - UnknownFieldSet.newBuilder(getUnknownFields());
|
| - while (true) {
|
| - final int tag = input.readTag();
|
| - if (tag == 0) {
|
| - break;
|
| - }
|
| -
|
| - if (!mergeFieldFrom(input, unknownFields, extensionRegistry,
|
| - getDescriptorForType(), this, null, tag)) {
|
| - // end group tag
|
| - break;
|
| - }
|
| - }
|
| - setUnknownFields(unknownFields.build());
|
| - return (BuilderType) this;
|
| - }
|
| -
|
| - /** helper method to handle {@code builder} and {@code extensions}. */
|
| - private static void addRepeatedField(
|
| - Message.Builder builder,
|
| - FieldSet<FieldDescriptor> extensions,
|
| - FieldDescriptor field,
|
| - Object value) {
|
| - if (builder != null) {
|
| - builder.addRepeatedField(field, value);
|
| - } else {
|
| - extensions.addRepeatedField(field, value);
|
| - }
|
| - }
|
| -
|
| - /** 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);
|
| - }
|
| - }
|
| -
|
| - /** helper method to handle {@code builder} and {@code extensions}. */
|
| - private static boolean hasOriginalMessage(
|
| - Message.Builder builder,
|
| - FieldSet<FieldDescriptor> extensions,
|
| - FieldDescriptor field) {
|
| - if (builder != null) {
|
| - return builder.hasField(field);
|
| - } else {
|
| - return extensions.hasField(field);
|
| - }
|
| - }
|
| -
|
| - /** helper method to handle {@code builder} and {@code extensions}. */
|
| - private static Message getOriginalMessage(
|
| - Message.Builder builder,
|
| - FieldSet<FieldDescriptor> extensions,
|
| - FieldDescriptor field) {
|
| - if (builder != null) {
|
| - return (Message) builder.getField(field);
|
| - } else {
|
| - return (Message) extensions.getField(field);
|
| - }
|
| - }
|
| -
|
| - /** helper method to handle {@code builder} and {@code extensions}. */
|
| - private static void mergeOriginalMessage(
|
| - Message.Builder builder,
|
| - FieldSet<FieldDescriptor> extensions,
|
| - FieldDescriptor field,
|
| - Message.Builder subBuilder) {
|
| - Message originalMessage = getOriginalMessage(builder, extensions, field);
|
| - if (originalMessage != null) {
|
| - subBuilder.mergeFrom(originalMessage);
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Like {@link #mergeFrom(CodedInputStream, ExtensionRegistryLite)}, but
|
| - * parses a single field.
|
| - *
|
| - * 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.
|
| - *
|
| - * 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;
|
| - }
|
| -
|
| - /**
|
| - * Called by {@code #mergeFieldFrom()} to parse a MessageSet extension.
|
| - * If {@code builder} is not null, this method will merge MessageSet into
|
| - * the builder. Otherwise, it will merge the MessageSet into {@code
|
| - * extensions}.
|
| - */
|
| - private static void mergeMessageSetExtensionFromCodedStream(
|
| - CodedInputStream input,
|
| - UnknownFieldSet.Builder unknownFields,
|
| - ExtensionRegistryLite extensionRegistry,
|
| - Descriptor type,
|
| - Message.Builder builder,
|
| - FieldSet<FieldDescriptor> extensions) 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 = ((ExtensionRegistry) extensionRegistry)
|
| - .findExtensionByNumber(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, builder, extensions);
|
| - 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, builder, extensions);
|
| - } 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 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);
|
| - }
|
| - }
|
| -
|
| - 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);
|
| - }
|
| - }
|
| - }
|
| -
|
| - public BuilderType mergeUnknownFields(final UnknownFieldSet unknownFields) {
|
| - setUnknownFields(
|
| - UnknownFieldSet.newBuilder(getUnknownFields())
|
| - .mergeFrom(unknownFields)
|
| - .build());
|
| - return (BuilderType) this;
|
| - }
|
| -
|
| - public Message.Builder getFieldBuilder(final FieldDescriptor field) {
|
| - throw new UnsupportedOperationException(
|
| - "getFieldBuilder() called on an unsupported message type.");
|
| - }
|
| -
|
| - /**
|
| - * Construct an UninitializedMessageException reporting missing fields in
|
| - * the given message.
|
| - */
|
| - protected static UninitializedMessageException
|
| - newUninitializedMessageException(Message message) {
|
| - return new UninitializedMessageException(findMissingFields(message));
|
| - }
|
| -
|
| - /**
|
| - * Populates {@code this.missingFields} with the full "path" of each
|
| - * missing required field in the given message.
|
| - */
|
| - private static List<String> findMissingFields(
|
| - final MessageOrBuilder message) {
|
| - final List<String> results = new ArrayList<String>();
|
| - findMissingFields(message, "", results);
|
| - return results;
|
| - }
|
| -
|
| - /** Recursive helper implementing {@link #findMissingFields(Message)}. */
|
| - private static void findMissingFields(final MessageOrBuilder message,
|
| - final String prefix,
|
| - final List<String> results) {
|
| - for (final FieldDescriptor field :
|
| - message.getDescriptorForType().getFields()) {
|
| - if (field.isRequired() && !message.hasField(field)) {
|
| - results.add(prefix + field.getName());
|
| - }
|
| - }
|
| -
|
| - for (final Map.Entry<FieldDescriptor, Object> entry :
|
| - message.getAllFields().entrySet()) {
|
| - final FieldDescriptor field = entry.getKey();
|
| - final Object value = entry.getValue();
|
| -
|
| - if (field.getJavaType() == 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);
|
| - }
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| - private static String subMessagePrefix(final String prefix,
|
| - final 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();
|
| - }
|
| -
|
| - // ===============================================================
|
| - // The following definitions seem to be required in order to make javac
|
| - // not produce weird errors like:
|
| - //
|
| - // java/com/google/protobuf/DynamicMessage.java:203: types
|
| - // com.google.protobuf.AbstractMessage.Builder<
|
| - // com.google.protobuf.DynamicMessage.Builder> and
|
| - // com.google.protobuf.AbstractMessage.Builder<
|
| - // com.google.protobuf.DynamicMessage.Builder> are incompatible; both
|
| - // define mergeFrom(com.google.protobuf.ByteString), but with unrelated
|
| - // return types.
|
| - //
|
| - // Strangely, these lines are only needed if javac is invoked separately
|
| - // on AbstractMessage.java and AbstractMessageLite.java. If javac is
|
| - // invoked on both simultaneously, it works. (Or maybe the important
|
| - // point is whether or not DynamicMessage.java is compiled together with
|
| - // AbstractMessageLite.java -- not sure.) I suspect this is a compiler
|
| - // bug.
|
| -
|
| - @Override
|
| - public BuilderType mergeFrom(final ByteString data)
|
| - throws InvalidProtocolBufferException {
|
| - return super.mergeFrom(data);
|
| - }
|
| -
|
| - @Override
|
| - public BuilderType mergeFrom(
|
| - final ByteString data,
|
| - final ExtensionRegistryLite extensionRegistry)
|
| - throws InvalidProtocolBufferException {
|
| - return super.mergeFrom(data, extensionRegistry);
|
| - }
|
| -
|
| - @Override
|
| - public BuilderType mergeFrom(final byte[] data)
|
| - throws InvalidProtocolBufferException {
|
| - return super.mergeFrom(data);
|
| - }
|
| -
|
| - @Override
|
| - public BuilderType mergeFrom(
|
| - final byte[] data, final int off, final int len)
|
| - throws InvalidProtocolBufferException {
|
| - return super.mergeFrom(data, off, len);
|
| - }
|
| -
|
| - @Override
|
| - public BuilderType mergeFrom(
|
| - final byte[] data,
|
| - final ExtensionRegistryLite extensionRegistry)
|
| - throws InvalidProtocolBufferException {
|
| - return super.mergeFrom(data, extensionRegistry);
|
| - }
|
| -
|
| - @Override
|
| - public BuilderType mergeFrom(
|
| - final byte[] data, final int off, final int len,
|
| - final ExtensionRegistryLite extensionRegistry)
|
| - throws InvalidProtocolBufferException {
|
| - return super.mergeFrom(data, off, len, extensionRegistry);
|
| - }
|
| -
|
| - @Override
|
| - public BuilderType mergeFrom(final InputStream input)
|
| - throws IOException {
|
| - return super.mergeFrom(input);
|
| - }
|
| -
|
| - @Override
|
| - public BuilderType mergeFrom(
|
| - final InputStream input,
|
| - final ExtensionRegistryLite extensionRegistry)
|
| - throws IOException {
|
| - return super.mergeFrom(input, extensionRegistry);
|
| - }
|
| -
|
| - @Override
|
| - public boolean mergeDelimitedFrom(final InputStream input)
|
| - throws IOException {
|
| - return super.mergeDelimitedFrom(input);
|
| - }
|
| -
|
| - @Override
|
| - public boolean mergeDelimitedFrom(
|
| - final InputStream input,
|
| - final ExtensionRegistryLite extensionRegistry)
|
| - throws IOException {
|
| - return super.mergeDelimitedFrom(input, extensionRegistry);
|
| - }
|
| -
|
| - }
|
| -}
|
|
|