All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.protobuf.GeneratedMessageLite Maven / Gradle / Ivy

There is a newer version: 5.3.3
Show newest version
// 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 java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Lite version of {@link GeneratedMessage}.
 *
 * @author [email protected] Kenton Varda
 */
public abstract class GeneratedMessageLite extends AbstractMessageLite {
    protected GeneratedMessageLite() {
    }

    /**
     * For use by generated code only.
     */
    public static 
    GeneratedExtension
    newGeneratedExtension() {
        return new GeneratedExtension();
    }

    // =================================================================
    // Extensions-related stuff

    @SuppressWarnings("unchecked")
    public abstract static class Builder
            extends AbstractMessageLite.Builder {
        protected Builder() {
        }

        // This is implemented here only to work around an apparent bug in the
        // Java compiler and/or build system.  See bug #1898463.  The mere presence
        // of this dummy clone() implementation makes it go away.
        @Override
        public BuilderType clone() {
            throw new UnsupportedOperationException(
                    "This is supposed to be overridden by subclasses.");
        }

        /**
         * All subclasses implement this.
         */
        public abstract BuilderType mergeFrom(MessageType message);

        // Defined here for return type covariance.
        public abstract MessageType getDefaultInstanceForType();

        /**
         * Get the message being built.  We don't just pass this to the
         * constructor because it becomes null when build() is called.
         */
        protected abstract MessageType internalGetResult();

        /**
         * Called by subclasses to parse an unknown field.
         *
         * @return {@code true} unless the tag is an end-group tag.
         */
        protected boolean parseUnknownField(
                final CodedInputStream input,
                final ExtensionRegistryLite extensionRegistry,
                final int tag) throws IOException {
            return input.skipField(tag);
        }
    }

    /**
     * Lite equivalent of {@link GeneratedMessage.ExtendableMessage}.
     */
    public abstract static class ExtendableMessage<
            MessageType extends ExtendableMessage>
            extends GeneratedMessageLite {
        private final FieldSet extensions =
                FieldSet.newFieldSet();

        protected ExtendableMessage() {
        }

        private void verifyExtensionContainingType(
                final GeneratedExtension extension) {
            if (extension.getContainingTypeDefaultInstance() !=
                    getDefaultInstanceForType()) {
                // This can only happen if someone uses unchecked operations.
                throw new IllegalArgumentException(
                        "This extension is for a different message type.  Please make " +
                                "sure that you are not suppressing any generics type warnings.");
            }
        }

        /**
         * Check if a singular extension is present.
         */
        public final boolean hasExtension(
                final GeneratedExtension extension) {
            verifyExtensionContainingType(extension);
            return extensions.hasField(extension.descriptor);
        }

        /**
         * Get the number of elements in a repeated extension.
         */
        public final  int getExtensionCount(
                final GeneratedExtension> extension) {
            verifyExtensionContainingType(extension);
            return extensions.getRepeatedFieldCount(extension.descriptor);
        }

        /**
         * Get the value of an extension.
         */
        @SuppressWarnings("unchecked")
        public final  Type getExtension(
                final GeneratedExtension extension) {
            verifyExtensionContainingType(extension);
            final Object value = extensions.getField(extension.descriptor);
            if (value == null) {
                return extension.defaultValue;
            } else {
                return (Type) value;
            }
        }

        /**
         * Get one element of a repeated extension.
         */
        @SuppressWarnings("unchecked")
        public final  Type getExtension(
                final GeneratedExtension> extension,
                final int index) {
            verifyExtensionContainingType(extension);
            return (Type) extensions.getRepeatedField(extension.descriptor, index);
        }

        /**
         * Called by subclasses to check if all extensions are initialized.
         */
        protected boolean extensionsAreInitialized() {
            return extensions.isInitialized();
        }

        protected ExtensionWriter newExtensionWriter() {
            return new ExtensionWriter(false);
        }

        protected ExtensionWriter newMessageSetExtensionWriter() {
            return new ExtensionWriter(true);
        }

        /**
         * Called by subclasses to compute the size of extensions.
         */
        protected int extensionsSerializedSize() {
            return extensions.getSerializedSize();
        }

        protected int extensionsSerializedSizeAsMessageSet() {
            return extensions.getMessageSetSerializedSize();
        }

        /**
         * Used by subclasses to serialize extensions.  Extension ranges may be
         * interleaved with field numbers, but we must write them in canonical
         * (sorted by field number) order.  ExtensionWriter helps us write
         * individual ranges of extensions at once.
         */
        protected class ExtensionWriter {
            // Imagine how much simpler this code would be if Java iterators had
            // a way to get the next element without advancing the iterator.

            private final Iterator> iter =
                    extensions.iterator();
            private final boolean messageSetWireFormat;
            private Map.Entry next;

            private ExtensionWriter(boolean messageSetWireFormat) {
                if (iter.hasNext()) {
                    next = iter.next();
                }
                this.messageSetWireFormat = messageSetWireFormat;
            }

            public void writeUntil(final int end, final CodedOutputStream output)
                    throws IOException {
                while (next != null && next.getKey().getNumber() < end) {
                    ExtensionDescriptor extension = next.getKey();
                    if (messageSetWireFormat && extension.getLiteJavaType() ==
                            WireFormat.JavaType.MESSAGE &&
                            !extension.isRepeated()) {
                        output.writeMessageSetExtension(extension.getNumber(),
                                (MessageLite) next.getValue());
                    } else {
                        FieldSet.writeField(extension, next.getValue(), output);
                    }
                    if (iter.hasNext()) {
                        next = iter.next();
                    } else {
                        next = null;
                    }
                }
            }
        }
    }

    // -----------------------------------------------------------------

    /**
     * Lite equivalent of {@link GeneratedMessage.ExtendableBuilder}.
     */
    @SuppressWarnings("unchecked")
    public abstract static class ExtendableBuilder<
            MessageType extends ExtendableMessage,
            BuilderType extends ExtendableBuilder>
            extends Builder {
        protected ExtendableBuilder() {
        }

        // This is implemented here only to work around an apparent bug in the
        // Java compiler and/or build system.  See bug #1898463.  The mere presence
        // of this dummy clone() implementation makes it go away.
        @Override
        public BuilderType clone() {
            throw new UnsupportedOperationException(
                    "This is supposed to be overridden by subclasses.");
        }

        @Override
        protected abstract MessageType internalGetResult();

        /**
         * Check if a singular extension is present.
         */
        public final boolean hasExtension(
                final GeneratedExtension extension) {
            return internalGetResult().hasExtension(extension);
        }

        /**
         * Get the number of elements in a repeated extension.
         */
        public final  int getExtensionCount(
                final GeneratedExtension> extension) {
            return internalGetResult().getExtensionCount(extension);
        }

        /**
         * Get the value of an extension.
         */
        public final  Type getExtension(
                final GeneratedExtension extension) {
            return internalGetResult().getExtension(extension);
        }

        /**
         * Get one element of a repeated extension.
         */
        public final  Type getExtension(
                final GeneratedExtension> extension,
                final int index) {
            return internalGetResult().getExtension(extension, index);
        }

        /**
         * Set the value of an extension.
         */
        public final  BuilderType setExtension(
                final GeneratedExtension extension,
                final Type value) {
            final ExtendableMessage message = internalGetResult();
            message.verifyExtensionContainingType(extension);
            message.extensions.setField(extension.descriptor, value);
            return (BuilderType) this;
        }

        /**
         * Set the value of one element of a repeated extension.
         */
        public final  BuilderType setExtension(
                final GeneratedExtension> extension,
                final int index, final Type value) {
            final ExtendableMessage message = internalGetResult();
            message.verifyExtensionContainingType(extension);
            message.extensions.setRepeatedField(extension.descriptor, index, value);
            return (BuilderType) this;
        }

        /**
         * Append a value to a repeated extension.
         */
        public final  BuilderType addExtension(
                final GeneratedExtension> extension,
                final Type value) {
            final ExtendableMessage message = internalGetResult();
            message.verifyExtensionContainingType(extension);
            message.extensions.addRepeatedField(extension.descriptor, value);
            return (BuilderType) this;
        }

        /**
         * Clear an extension.
         */
        public final  BuilderType clearExtension(
                final GeneratedExtension extension) {
            final ExtendableMessage message = internalGetResult();
            message.verifyExtensionContainingType(extension);
            message.extensions.clearField(extension.descriptor);
            return (BuilderType) 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 extensions =
                    ((ExtendableMessage) internalGetResult()).extensions;

            final int wireType = WireFormat.getTagWireType(tag);
            final int fieldNumber = WireFormat.getTagFieldNumber(tag);

            final GeneratedExtension 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;
        }

        protected final void mergeExtensionFields(final MessageType other) {
            ((ExtendableMessage) internalGetResult()).extensions.mergeFrom(
                    ((ExtendableMessage) other).extensions);
        }
    }

    private static final class ExtensionDescriptor
            implements FieldSet.FieldDescriptorLite<
            ExtensionDescriptor> {
        private final Internal.EnumLiteMap enumTypeMap;
        private final int number;
        private final WireFormat.FieldType type;
        private final boolean isRepeated;
        private final boolean isPacked;
        private ExtensionDescriptor(
                final Internal.EnumLiteMap enumTypeMap,
                final int number,
                final WireFormat.FieldType type,
                final boolean isRepeated,
                final boolean isPacked) {
            this.enumTypeMap = enumTypeMap;
            this.number = number;
            this.type = type;
            this.isRepeated = isRepeated;
            this.isPacked = isPacked;
        }

        public int getNumber() {
            return number;
        }

        public WireFormat.FieldType getLiteType() {
            return type;
        }

        public WireFormat.JavaType getLiteJavaType() {
            return type.getJavaType();
        }

        public boolean isRepeated() {
            return isRepeated;
        }

        public boolean isPacked() {
            return isPacked;
        }

        public Internal.EnumLiteMap getEnumType() {
            return enumTypeMap;
        }

        @SuppressWarnings("unchecked")
        public MessageLite.Builder internalMergeFrom(
                MessageLite.Builder to, MessageLite from) {
            return ((Builder) to).mergeFrom((GeneratedMessageLite) from);
        }

        public int compareTo(ExtensionDescriptor other) {
            return number - other.number;
        }
    }

    /**
     * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}.
     * 

* Users should ignore the contents of this class and only use objects of * this type as parameters to extension accessors and ExtensionRegistry.add(). */ public static final class GeneratedExtension< ContainingType extends MessageLite, Type> { private ContainingType containingTypeDefaultInstance; private Type defaultValue; private MessageLite messageDefaultInstance; private ExtensionDescriptor descriptor; // We can't always initialize a GeneratedExtension when we first construct // it due to initialization order difficulties (namely, the default // instances may not have been constructed yet). So, we construct an // uninitialized GeneratedExtension once, then call internalInit() on it // later. Generated code will always call internalInit() on all extensions // as part of the static initialization code, and internalInit() throws an // exception if called more than once, so this method is useless to users. private GeneratedExtension() { } private void internalInit( final ContainingType containingTypeDefaultInstance, final Type defaultValue, final MessageLite messageDefaultInstance, final ExtensionDescriptor descriptor) { this.containingTypeDefaultInstance = containingTypeDefaultInstance; this.defaultValue = defaultValue; this.messageDefaultInstance = messageDefaultInstance; this.descriptor = descriptor; } /** * For use by generated code only. */ public void internalInitSingular( final ContainingType containingTypeDefaultInstance, final Type defaultValue, final MessageLite messageDefaultInstance, final Internal.EnumLiteMap enumTypeMap, final int number, final WireFormat.FieldType type) { internalInit( containingTypeDefaultInstance, defaultValue, messageDefaultInstance, new ExtensionDescriptor(enumTypeMap, number, type, false /* isRepeated */, false /* isPacked */)); } /** * For use by generated code only. */ public void internalInitRepeated( final ContainingType containingTypeDefaultInstance, final MessageLite messageDefaultInstance, final Internal.EnumLiteMap enumTypeMap, final int number, final WireFormat.FieldType type, final boolean isPacked) { internalInit( containingTypeDefaultInstance, (Type) Collections.emptyList(), messageDefaultInstance, new ExtensionDescriptor( enumTypeMap, number, type, true /* isRepeated */, isPacked)); } /** * Default instance of the type being extended, used to identify that type. */ public ContainingType getContainingTypeDefaultInstance() { return containingTypeDefaultInstance; } /** * Get the field number. */ public int getNumber() { return descriptor.getNumber(); } /** * If the extension is an embedded message, this is the default instance of * that type. */ public MessageLite getMessageDefaultInstance() { return messageDefaultInstance; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy