// Protocol Buffers - Google's data interchange format
// Copyright 2013 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.nano;

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

/**
 * Represents an extension.
 *
 * @author bduff@google.com (Brian Duff)
 * @author maxtroy@google.com (Max Cai)
 * @param <M> the type of the extendable message this extension is for.
 * @param <T> the Java type of the extension; see {@link #clazz}.
 */
public class Extension<M extends ExtendableMessageNano<M>, T> {

    /*
     * Because we typically only define message-typed extensions, the Extension class hierarchy is
     * designed as follows, to allow a big amount of code in this file to be removed by ProGuard:
     *
     *            Extension          // ready to use for message/group typed extensions
     *                Δ
     *                |
     *       PrimitiveExtension      // for primitive/enum typed extensions
     */

    public static final int TYPE_DOUBLE   = 1;
    public static final int TYPE_FLOAT    = 2;
    public static final int TYPE_INT64    = 3;
    public static final int TYPE_UINT64   = 4;
    public static final int TYPE_INT32    = 5;
    public static final int TYPE_FIXED64  = 6;
    public static final int TYPE_FIXED32  = 7;
    public static final int TYPE_BOOL     = 8;
    public static final int TYPE_STRING   = 9;
    public static final int TYPE_GROUP    = 10;
    public static final int TYPE_MESSAGE  = 11;
    public static final int TYPE_BYTES    = 12;
    public static final int TYPE_UINT32   = 13;
    public static final int TYPE_ENUM     = 14;
    public static final int TYPE_SFIXED32 = 15;
    public static final int TYPE_SFIXED64 = 16;
    public static final int TYPE_SINT32   = 17;
    public static final int TYPE_SINT64   = 18;

    /**
     * Creates an {@code Extension} of the given message type and tag number.
     * Should be used by the generated code only.
     *
     * @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
     * @deprecated use {@link #createMessageTyped(int, Class, long)} instead.
     */
    @Deprecated
    public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
            Extension<M, T> createMessageTyped(int type, Class<T> clazz, int tag) {
        return new Extension<M, T>(type, clazz, tag, false);
    }

    // Note: these create...() methods take a long for the tag parameter,
    // because tags are represented as unsigned ints, and these values exist
    // in generated code as long values. However, they can fit in 32-bits, so
    // it's safe to cast them to int without loss of precision.

    /**
     * Creates an {@code Extension} of the given message type and tag number.
     * Should be used by the generated code only.
     *
     * @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
     */
    public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
            Extension<M, T> createMessageTyped(int type, Class<T> clazz, long tag) {
        return new Extension<M, T>(type, clazz, (int) tag, false);
    }

    /**
     * Creates a repeated {@code Extension} of the given message type and tag number.
     * Should be used by the generated code only.
     *
     * @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
     */
    public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
            Extension<M, T[]> createRepeatedMessageTyped(int type, Class<T[]> clazz, long tag) {
        return new Extension<M, T[]>(type, clazz, (int) tag, true);
    }

    /**
     * Creates an {@code Extension} of the given primitive type and tag number.
     * Should be used by the generated code only.
     *
     * @param type one of {@code TYPE_*}, except {@link #TYPE_MESSAGE} and {@link #TYPE_GROUP}
     * @param clazz the boxed Java type of this extension
     */
    public static <M extends ExtendableMessageNano<M>, T>
            Extension<M, T> createPrimitiveTyped(int type, Class<T> clazz, long tag) {
        return new PrimitiveExtension<M, T>(type, clazz, (int) tag, false, 0, 0);
    }

    /**
     * Creates a repeated {@code Extension} of the given primitive type and tag number.
     * Should be used by the generated code only.
     *
     * @param type one of {@code TYPE_*}, except {@link #TYPE_MESSAGE} and {@link #TYPE_GROUP}
     * @param clazz the Java array type of this extension, with an unboxed component type
     */
    public static <M extends ExtendableMessageNano<M>, T>
            Extension<M, T> createRepeatedPrimitiveTyped(
                    int type, Class<T> clazz, long tag, long nonPackedTag, long packedTag) {
        return new PrimitiveExtension<M, T>(type, clazz, (int) tag, true,
            (int) nonPackedTag, (int) packedTag);
    }

    /**
     * Protocol Buffer type of this extension; one of the {@code TYPE_} constants.
     */
    protected final int type;

    /**
     * Java type of this extension. For a singular extension, this is the boxed Java type for the
     * Protocol Buffer {@link #type}; for a repeated extension, this is an array type whose
     * component type is the unboxed Java type for {@link #type}. For example, for a singular
     * {@code int32}/{@link #TYPE_INT32} extension, this equals {@code Integer.class}; for a
     * repeated {@code int32} extension, this equals {@code int[].class}.
     */
    protected final Class<T> clazz;

    /**
     * Tag number of this extension. The data should be viewed as an unsigned 32-bit value.
     */
    public final int tag;

    /**
     * Whether this extension is repeated.
     */
    protected final boolean repeated;

    private Extension(int type, Class<T> clazz, int tag, boolean repeated) {
        this.type = type;
        this.clazz = clazz;
        this.tag = tag;
        this.repeated = repeated;
    }

    /**
     * Returns the value of this extension stored in the given list of unknown fields, or
     * {@code null} if no unknown fields matches this extension.
     *
     * @param unknownFields a list of {@link UnknownFieldData}. All of the elements must have a tag
     *                      that matches this Extension's tag.
     *
     */
    final T getValueFrom(List<UnknownFieldData> unknownFields) {
        if (unknownFields == null) {
            return null;
        }
        return repeated ? getRepeatedValueFrom(unknownFields) : getSingularValueFrom(unknownFields);
    }

    private T getRepeatedValueFrom(List<UnknownFieldData> unknownFields) {
        // For repeated extensions, read all matching unknown fields in their original order.
        List<Object> resultList = new ArrayList<Object>();
        for (int i = 0; i < unknownFields.size(); i++) {
            UnknownFieldData data = unknownFields.get(i);
            if (data.bytes.length != 0) {
                readDataInto(data, resultList);
            }
        }

        int resultSize = resultList.size();
        if (resultSize == 0) {
            return null;
        } else {
            T result = clazz.cast(Array.newInstance(clazz.getComponentType(), resultSize));
            for (int i = 0; i < resultSize; i++) {
                Array.set(result, i, resultList.get(i));
            }
            return result;
        }
    }

    private T getSingularValueFrom(List<UnknownFieldData> unknownFields) {
        // For singular extensions, get the last piece of data stored under this extension.
        if (unknownFields.isEmpty()) {
            return null;
        }
        UnknownFieldData lastData = unknownFields.get(unknownFields.size() - 1);
        return clazz.cast(readData(CodedInputByteBufferNano.newInstance(lastData.bytes)));
    }

    protected Object readData(CodedInputByteBufferNano input) {
        // This implementation is for message/group extensions.
        Class<?> messageType = repeated ? clazz.getComponentType() : clazz;
        try {
            switch (type) {
                case TYPE_GROUP:
                    MessageNano group = (MessageNano) messageType.newInstance();
                    input.readGroup(group, WireFormatNano.getTagFieldNumber(tag));
                    return group;
                case TYPE_MESSAGE:
                    MessageNano message = (MessageNano) messageType.newInstance();
                    input.readMessage(message);
                    return message;
                default:
                    throw new IllegalArgumentException("Unknown type " + type);
            }
        } catch (InstantiationException e) {
            throw new IllegalArgumentException(
                    "Error creating instance of class " + messageType, e);
        } catch (IllegalAccessException e) {
            throw new IllegalArgumentException(
                    "Error creating instance of class " + messageType, e);
        } catch (IOException e) {
            throw new IllegalArgumentException("Error reading extension field", e);
        }
    }

    protected void readDataInto(UnknownFieldData data, List<Object> resultList) {
        // This implementation is for message/group extensions.
        resultList.add(readData(CodedInputByteBufferNano.newInstance(data.bytes)));
    }

    void writeTo(Object value, CodedOutputByteBufferNano output) throws IOException {
        if (repeated) {
            writeRepeatedData(value, output);
        } else {
            writeSingularData(value, output);
        }
    }

    protected void writeSingularData(Object value, CodedOutputByteBufferNano out) {
        // This implementation is for message/group extensions.
        try {
            out.writeRawVarint32(tag);
            switch (type) {
                case TYPE_GROUP:
                    MessageNano groupValue = (MessageNano) value;
                    int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
                    out.writeGroupNoTag(groupValue);
                    // The endgroup tag must be included in the data payload.
                    out.writeTag(fieldNumber, WireFormatNano.WIRETYPE_END_GROUP);
                    break;
                case TYPE_MESSAGE:
                    MessageNano messageValue = (MessageNano) value;
                    out.writeMessageNoTag(messageValue);
                    break;
                default:
                    throw new IllegalArgumentException("Unknown type " + type);
            }
        } catch (IOException e) {
            // Should not happen
            throw new IllegalStateException(e);
        }
    }

    protected void writeRepeatedData(Object array, CodedOutputByteBufferNano output) {
        // This implementation is for non-packed extensions.
        int arrayLength = Array.getLength(array);
        for (int i = 0; i < arrayLength; i++) {
            Object element = Array.get(array, i);
            if (element != null) {
                writeSingularData(element, output);
            }
        }
    }

    int computeSerializedSize(Object value) {
        if (repeated) {
            return computeRepeatedSerializedSize(value);
        } else {
            return computeSingularSerializedSize(value);
        }
    }

    protected int computeRepeatedSerializedSize(Object array) {
        // This implementation is for non-packed extensions.
        int size = 0;
        int arrayLength = Array.getLength(array);
        for (int i = 0; i < arrayLength; i++) {
            Object element = Array.get(array, i);
            if (element != null) {
                size += computeSingularSerializedSize(Array.get(array, i));
            }
        }
        return size;
    }

    protected int computeSingularSerializedSize(Object value) {
        // This implementation is for message/group extensions.
        int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
        switch (type) {
            case TYPE_GROUP:
                MessageNano groupValue = (MessageNano) value;
                return CodedOutputByteBufferNano.computeGroupSize(fieldNumber, groupValue);
            case TYPE_MESSAGE:
                MessageNano messageValue = (MessageNano) value;
                return CodedOutputByteBufferNano.computeMessageSize(fieldNumber, messageValue);
            default:
                throw new IllegalArgumentException("Unknown type " + type);
        }
    }

    /**
     * Represents an extension of a primitive (including enum) type. If there is no primitive
     * extensions, this subclass will be removable by ProGuard.
     */
    private static class PrimitiveExtension<M extends ExtendableMessageNano<M>, T>
            extends Extension<M, T> {

        /**
         * Tag of a piece of non-packed data from the wire compatible with this extension.
         */
        private final int nonPackedTag;

        /**
         * Tag of a piece of packed data from the wire compatible with this extension.
         * 0 if the type of this extension is not packable.
         */
        private final int packedTag;

        public PrimitiveExtension(int type, Class<T> clazz, int tag, boolean repeated,
                int nonPackedTag, int packedTag) {
            super(type, clazz, tag, repeated);
            this.nonPackedTag = nonPackedTag;
            this.packedTag = packedTag;
        }

        @Override
        protected Object readData(CodedInputByteBufferNano input) {
            try {
                switch (type) {
                    case TYPE_DOUBLE:
                        return input.readDouble();
                    case TYPE_FLOAT:
                        return input.readFloat();
                    case TYPE_INT64:
                        return input.readInt64();
                    case TYPE_UINT64:
                        return input.readUInt64();
                    case TYPE_INT32:
                        return input.readInt32();
                    case TYPE_FIXED64:
                        return input.readFixed64();
                    case TYPE_FIXED32:
                        return input.readFixed32();
                    case TYPE_BOOL:
                        return input.readBool();
                    case TYPE_STRING:
                        return input.readString();
                    case TYPE_BYTES:
                        return input.readBytes();
                    case TYPE_UINT32:
                        return input.readUInt32();
                    case TYPE_ENUM:
                        return input.readEnum();
                    case TYPE_SFIXED32:
                        return input.readSFixed32();
                    case TYPE_SFIXED64:
                        return input.readSFixed64();
                    case TYPE_SINT32:
                        return input.readSInt32();
                    case TYPE_SINT64:
                        return input.readSInt64();
                    default:
                        throw new IllegalArgumentException("Unknown type " + type);
                }
            } catch (IOException e) {
                throw new IllegalArgumentException("Error reading extension field", e);
            }
        }

        @Override
        protected void readDataInto(UnknownFieldData data, List<Object> resultList) {
            // This implementation is for primitive typed extensions,
            // which can read both packed and non-packed data.
            if (data.tag == nonPackedTag) {
                resultList.add(readData(CodedInputByteBufferNano.newInstance(data.bytes)));
            } else {
                CodedInputByteBufferNano buffer =
                        CodedInputByteBufferNano.newInstance(data.bytes);
                try {
                    buffer.pushLimit(buffer.readRawVarint32()); // length limit
                } catch (IOException e) {
                    throw new IllegalArgumentException("Error reading extension field", e);
                }
                while (!buffer.isAtEnd()) {
                    resultList.add(readData(buffer));
                }
            }
        }

        @Override
        protected final void writeSingularData(Object value, CodedOutputByteBufferNano output) {
            try {
                output.writeRawVarint32(tag);
                switch (type) {
                    case TYPE_DOUBLE:
                        Double doubleValue = (Double) value;
                        output.writeDoubleNoTag(doubleValue);
                        break;
                    case TYPE_FLOAT:
                        Float floatValue = (Float) value;
                        output.writeFloatNoTag(floatValue);
                        break;
                    case TYPE_INT64:
                        Long int64Value = (Long) value;
                        output.writeInt64NoTag(int64Value);
                        break;
                    case TYPE_UINT64:
                        Long uint64Value = (Long) value;
                        output.writeUInt64NoTag(uint64Value);
                        break;
                    case TYPE_INT32:
                        Integer int32Value = (Integer) value;
                        output.writeInt32NoTag(int32Value);
                        break;
                    case TYPE_FIXED64:
                        Long fixed64Value = (Long) value;
                        output.writeFixed64NoTag(fixed64Value);
                        break;
                    case TYPE_FIXED32:
                        Integer fixed32Value = (Integer) value;
                        output.writeFixed32NoTag(fixed32Value);
                        break;
                    case TYPE_BOOL:
                        Boolean boolValue = (Boolean) value;
                        output.writeBoolNoTag(boolValue);
                        break;
                    case TYPE_STRING:
                        String stringValue = (String) value;
                        output.writeStringNoTag(stringValue);
                        break;
                    case TYPE_BYTES:
                        byte[] bytesValue = (byte[]) value;
                        output.writeBytesNoTag(bytesValue);
                        break;
                    case TYPE_UINT32:
                        Integer uint32Value = (Integer) value;
                        output.writeUInt32NoTag(uint32Value);
                        break;
                    case TYPE_ENUM:
                        Integer enumValue = (Integer) value;
                        output.writeEnumNoTag(enumValue);
                        break;
                    case TYPE_SFIXED32:
                        Integer sfixed32Value = (Integer) value;
                        output.writeSFixed32NoTag(sfixed32Value);
                        break;
                    case TYPE_SFIXED64:
                        Long sfixed64Value = (Long) value;
                        output.writeSFixed64NoTag(sfixed64Value);
                        break;
                    case TYPE_SINT32:
                        Integer sint32Value = (Integer) value;
                        output.writeSInt32NoTag(sint32Value);
                        break;
                    case TYPE_SINT64:
                        Long sint64Value = (Long) value;
                        output.writeSInt64NoTag(sint64Value);
                        break;
                    default:
                        throw new IllegalArgumentException("Unknown type " + type);
                }
            } catch (IOException e) {
                // Should not happen
                throw new IllegalStateException(e);
            }
        }

        @Override
        protected void writeRepeatedData(Object array, CodedOutputByteBufferNano output) {
            if (tag == nonPackedTag) {
                // Use base implementation for non-packed data
                super.writeRepeatedData(array, output);
            } else if (tag == packedTag) {
                // Packed. Note that the array element type is guaranteed to be primitive, so there
                // won't be any null elements, so no null check in this block.
                int arrayLength = Array.getLength(array);
                int dataSize = computePackedDataSize(array);

                try {
                    output.writeRawVarint32(tag);
                    output.writeRawVarint32(dataSize);
                    switch (type) {
                        case TYPE_BOOL:
                            for (int i = 0; i < arrayLength; i++) {
                                output.writeBoolNoTag(Array.getBoolean(array, i));
                            }
                            break;
                        case TYPE_FIXED32:
                            for (int i = 0; i < arrayLength; i++) {
                                output.writeFixed32NoTag(Array.getInt(array, i));
                            }
                            break;
                        case TYPE_SFIXED32:
                            for (int i = 0; i < arrayLength; i++) {
                                output.writeSFixed32NoTag(Array.getInt(array, i));
                            }
                            break;
                        case TYPE_FLOAT:
                            for (int i = 0; i < arrayLength; i++) {
                                output.writeFloatNoTag(Array.getFloat(array, i));
                            }
                            break;
                        case TYPE_FIXED64:
                            for (int i = 0; i < arrayLength; i++) {
                                output.writeFixed64NoTag(Array.getLong(array, i));
                            }
                            break;
                        case TYPE_SFIXED64:
                            for (int i = 0; i < arrayLength; i++) {
                                output.writeSFixed64NoTag(Array.getLong(array, i));
                            }
                            break;
                        case TYPE_DOUBLE:
                            for (int i = 0; i < arrayLength; i++) {
                                output.writeDoubleNoTag(Array.getDouble(array, i));
                            }
                            break;
                        case TYPE_INT32:
                            for (int i = 0; i < arrayLength; i++) {
                                output.writeInt32NoTag(Array.getInt(array, i));
                            }
                            break;
                        case TYPE_SINT32:
                            for (int i = 0; i < arrayLength; i++) {
                                output.writeSInt32NoTag(Array.getInt(array, i));
                            }
                            break;
                        case TYPE_UINT32:
                            for (int i = 0; i < arrayLength; i++) {
                                output.writeUInt32NoTag(Array.getInt(array, i));
                            }
                            break;
                        case TYPE_INT64:
                            for (int i = 0; i < arrayLength; i++) {
                                output.writeInt64NoTag(Array.getLong(array, i));
                            }
                            break;
                        case TYPE_SINT64:
                            for (int i = 0; i < arrayLength; i++) {
                                output.writeSInt64NoTag(Array.getLong(array, i));
                            }
                            break;
                        case TYPE_UINT64:
                            for (int i = 0; i < arrayLength; i++) {
                                output.writeUInt64NoTag(Array.getLong(array, i));
                            }
                            break;
                        case TYPE_ENUM:
                            for (int i = 0; i < arrayLength; i++) {
                                output.writeEnumNoTag(Array.getInt(array, i));
                            }
                            break;
                        default:
                            throw new IllegalArgumentException("Unpackable type " + type);
                    }
                } catch (IOException e) {
                    // Should not happen.
                    throw new IllegalStateException(e);
                }
            } else {
                throw new IllegalArgumentException("Unexpected repeated extension tag " + tag
                        + ", unequal to both non-packed variant " + nonPackedTag
                        + " and packed variant " + packedTag);
            }
        }

        private int computePackedDataSize(Object array) {
            int dataSize = 0;
            int arrayLength = Array.getLength(array);
            switch (type) {
                case TYPE_BOOL:
                    // Bools are stored as int32 but just as 0 or 1, so 1 byte each.
                    dataSize = arrayLength;
                    break;
                case TYPE_FIXED32:
                case TYPE_SFIXED32:
                case TYPE_FLOAT:
                    dataSize = arrayLength * CodedOutputByteBufferNano.LITTLE_ENDIAN_32_SIZE;
                    break;
                case TYPE_FIXED64:
                case TYPE_SFIXED64:
                case TYPE_DOUBLE:
                    dataSize = arrayLength * CodedOutputByteBufferNano.LITTLE_ENDIAN_64_SIZE;
                    break;
                case TYPE_INT32:
                    for (int i = 0; i < arrayLength; i++) {
                        dataSize += CodedOutputByteBufferNano.computeInt32SizeNoTag(
                                Array.getInt(array, i));
                    }
                    break;
                case TYPE_SINT32:
                    for (int i = 0; i < arrayLength; i++) {
                        dataSize += CodedOutputByteBufferNano.computeSInt32SizeNoTag(
                                Array.getInt(array, i));
                    }
                    break;
                case TYPE_UINT32:
                    for (int i = 0; i < arrayLength; i++) {
                        dataSize += CodedOutputByteBufferNano.computeUInt32SizeNoTag(
                                Array.getInt(array, i));
                    }
                    break;
                case TYPE_INT64:
                    for (int i = 0; i < arrayLength; i++) {
                        dataSize += CodedOutputByteBufferNano.computeInt64SizeNoTag(
                                Array.getLong(array, i));
                    }
                    break;
                case TYPE_SINT64:
                    for (int i = 0; i < arrayLength; i++) {
                        dataSize += CodedOutputByteBufferNano.computeSInt64SizeNoTag(
                                Array.getLong(array, i));
                    }
                    break;
                case TYPE_UINT64:
                    for (int i = 0; i < arrayLength; i++) {
                        dataSize += CodedOutputByteBufferNano.computeUInt64SizeNoTag(
                                Array.getLong(array, i));
                    }
                    break;
                case TYPE_ENUM:
                    for (int i = 0; i < arrayLength; i++) {
                        dataSize += CodedOutputByteBufferNano.computeEnumSizeNoTag(
                                Array.getInt(array, i));
                    }
                    break;
                default:
                    throw new IllegalArgumentException("Unexpected non-packable type " + type);
            }
            return dataSize;
        }

        @Override
        protected int computeRepeatedSerializedSize(Object array) {
            if (tag == nonPackedTag) {
                // Use base implementation for non-packed data
                return super.computeRepeatedSerializedSize(array);
            } else if (tag == packedTag) {
                // Packed.
                int dataSize = computePackedDataSize(array);
                int payloadSize =
                        dataSize + CodedOutputByteBufferNano.computeRawVarint32Size(dataSize);
                return payloadSize + CodedOutputByteBufferNano.computeRawVarint32Size(tag);
            } else {
                throw new IllegalArgumentException("Unexpected repeated extension tag " + tag
                        + ", unequal to both non-packed variant " + nonPackedTag
                        + " and packed variant " + packedTag);
            }
        }

        @Override
        protected final int computeSingularSerializedSize(Object value) {
            int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
            switch (type) {
                case TYPE_DOUBLE:
                    Double doubleValue = (Double) value;
                    return CodedOutputByteBufferNano.computeDoubleSize(fieldNumber, doubleValue);
                case TYPE_FLOAT:
                    Float floatValue = (Float) value;
                    return CodedOutputByteBufferNano.computeFloatSize(fieldNumber, floatValue);
                case TYPE_INT64:
                    Long int64Value = (Long) value;
                    return CodedOutputByteBufferNano.computeInt64Size(fieldNumber, int64Value);
                case TYPE_UINT64:
                    Long uint64Value = (Long) value;
                    return CodedOutputByteBufferNano.computeUInt64Size(fieldNumber, uint64Value);
                case TYPE_INT32:
                    Integer int32Value = (Integer) value;
                    return CodedOutputByteBufferNano.computeInt32Size(fieldNumber, int32Value);
                case TYPE_FIXED64:
                    Long fixed64Value = (Long) value;
                    return CodedOutputByteBufferNano.computeFixed64Size(fieldNumber, fixed64Value);
                case TYPE_FIXED32:
                    Integer fixed32Value = (Integer) value;
                    return CodedOutputByteBufferNano.computeFixed32Size(fieldNumber, fixed32Value);
                case TYPE_BOOL:
                    Boolean boolValue = (Boolean) value;
                    return CodedOutputByteBufferNano.computeBoolSize(fieldNumber, boolValue);
                case TYPE_STRING:
                    String stringValue = (String) value;
                    return CodedOutputByteBufferNano.computeStringSize(fieldNumber, stringValue);
                case TYPE_BYTES:
                    byte[] bytesValue = (byte[]) value;
                    return CodedOutputByteBufferNano.computeBytesSize(fieldNumber, bytesValue);
                case TYPE_UINT32:
                    Integer uint32Value = (Integer) value;
                    return CodedOutputByteBufferNano.computeUInt32Size(fieldNumber, uint32Value);
                case TYPE_ENUM:
                    Integer enumValue = (Integer) value;
                    return CodedOutputByteBufferNano.computeEnumSize(fieldNumber, enumValue);
                case TYPE_SFIXED32:
                    Integer sfixed32Value = (Integer) value;
                    return CodedOutputByteBufferNano.computeSFixed32Size(fieldNumber,
                            sfixed32Value);
                case TYPE_SFIXED64:
                    Long sfixed64Value = (Long) value;
                    return CodedOutputByteBufferNano.computeSFixed64Size(fieldNumber,
                            sfixed64Value);
                case TYPE_SINT32:
                    Integer sint32Value = (Integer) value;
                    return CodedOutputByteBufferNano.computeSInt32Size(fieldNumber, sint32Value);
                case TYPE_SINT64:
                    Long sint64Value = (Long) value;
                    return CodedOutputByteBufferNano.computeSInt64Size(fieldNumber, sint64Value);
                default:
                    throw new IllegalArgumentException("Unknown type " + type);
            }
        }
    }
}
