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

import java.io.IOException;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ReadOnlyBufferException;

/**
 * Encodes and writes protocol message fields.
 *
 * <p>This class contains two kinds of methods:  methods that write specific
 * protocol message constructs and field types (e.g. {@link #writeTag} and
 * {@link #writeInt32}) and methods that write low-level values (e.g.
 * {@link #writeRawVarint32} and {@link #writeRawBytes}).  If you are
 * writing encoded protocol messages, you should use the former methods, but if
 * you are writing some other format of your own design, use the latter.
 *
 * <p>This class is totally unsynchronized.
 *
 * @author kneton@google.com Kenton Varda
 */
public final class CodedOutputByteBufferNano {
  /* max bytes per java UTF-16 char in UTF-8 */
  private static final int MAX_UTF8_EXPANSION = 3;
  private final ByteBuffer buffer;

  private CodedOutputByteBufferNano(final byte[] buffer, final int offset,
                            final int length) {
    this(ByteBuffer.wrap(buffer, offset, length));
  }

  private CodedOutputByteBufferNano(final ByteBuffer buffer) {
    this.buffer = buffer;
    this.buffer.order(ByteOrder.LITTLE_ENDIAN);
  }

  /**
   * Create a new {@code CodedOutputStream} that writes directly to the given
   * byte array.  If more bytes are written than fit in the array,
   * {@link OutOfSpaceException} will be thrown.  Writing directly to a flat
   * array is faster than writing to an {@code OutputStream}.
   */
  public static CodedOutputByteBufferNano newInstance(final byte[] flatArray) {
    return newInstance(flatArray, 0, flatArray.length);
  }

  /**
   * Create a new {@code CodedOutputStream} that writes directly to the given
   * byte array slice.  If more bytes are written than fit in the slice,
   * {@link OutOfSpaceException} will be thrown.  Writing directly to a flat
   * array is faster than writing to an {@code OutputStream}.
   */
  public static CodedOutputByteBufferNano newInstance(final byte[] flatArray,
                                              final int offset,
                                              final int length) {
    return new CodedOutputByteBufferNano(flatArray, offset, length);
  }

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

  /** Write a {@code double} field, including tag, to the stream. */
  public void writeDouble(final int fieldNumber, final double value)
                          throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64);
    writeDoubleNoTag(value);
  }

  /** Write a {@code float} field, including tag, to the stream. */
  public void writeFloat(final int fieldNumber, final float value)
                         throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32);
    writeFloatNoTag(value);
  }

  /** Write a {@code uint64} field, including tag, to the stream. */
  public void writeUInt64(final int fieldNumber, final long value)
                          throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
    writeUInt64NoTag(value);
  }

  /** Write an {@code int64} field, including tag, to the stream. */
  public void writeInt64(final int fieldNumber, final long value)
                         throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
    writeInt64NoTag(value);
  }

  /** Write an {@code int32} field, including tag, to the stream. */
  public void writeInt32(final int fieldNumber, final int value)
                         throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
    writeInt32NoTag(value);
  }

  /** Write a {@code fixed64} field, including tag, to the stream. */
  public void writeFixed64(final int fieldNumber, final long value)
                           throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64);
    writeFixed64NoTag(value);
  }

  /** Write a {@code fixed32} field, including tag, to the stream. */
  public void writeFixed32(final int fieldNumber, final int value)
                           throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32);
    writeFixed32NoTag(value);
  }

  /** Write a {@code bool} field, including tag, to the stream. */
  public void writeBool(final int fieldNumber, final boolean value)
                        throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
    writeBoolNoTag(value);
  }

  /** Write a {@code string} field, including tag, to the stream. */
  public void writeString(final int fieldNumber, final String value)
                          throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
    writeStringNoTag(value);
  }

  /** Write a {@code group} field, including tag, to the stream. */
  public void writeGroup(final int fieldNumber, final MessageNano value)
                         throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_START_GROUP);
    writeGroupNoTag(value);
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_END_GROUP);
  }

  /** Write an embedded message field, including tag, to the stream. */
  public void writeMessage(final int fieldNumber, final MessageNano value)
                           throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
    writeMessageNoTag(value);
  }

  /** Write a {@code bytes} field, including tag, to the stream. */
  public void writeBytes(final int fieldNumber, final byte[] value)
                         throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
    writeBytesNoTag(value);
  }

  /** Write a {@code bytes} field, including tag, to the stream. */
  public void writeBytes(final int fieldNumber, final byte[] value,
                         final int offset, final int length)
                         throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
    writeBytesNoTag(value, offset, length);
  }

  /** Write a {@code uint32} field, including tag, to the stream. */
  public void writeUInt32(final int fieldNumber, final int value)
                          throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
    writeUInt32NoTag(value);
  }

  /**
   * Write an enum field, including tag, to the stream.  Caller is responsible
   * for converting the enum value to its numeric value.
   */
  public void writeEnum(final int fieldNumber, final int value)
                        throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
    writeEnumNoTag(value);
  }

  /** Write an {@code sfixed32} field, including tag, to the stream. */
  public void writeSFixed32(final int fieldNumber, final int value)
                            throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32);
    writeSFixed32NoTag(value);
  }

  /** Write an {@code sfixed64} field, including tag, to the stream. */
  public void writeSFixed64(final int fieldNumber, final long value)
                            throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64);
    writeSFixed64NoTag(value);
  }

  /** Write an {@code sint32} field, including tag, to the stream. */
  public void writeSInt32(final int fieldNumber, final int value)
                          throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
    writeSInt32NoTag(value);
  }

  /** Write an {@code sint64} field, including tag, to the stream. */
  public void writeSInt64(final int fieldNumber, final long value)
                          throws IOException {
    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
    writeSInt64NoTag(value);
  }

  /**
   * Write a MessageSet extension field to the stream.  For historical reasons,
   * the wire format differs from normal fields.
   */
//  public void writeMessageSetExtension(final int fieldNumber,
//                                       final MessageMicro value)
//                                       throws IOException {
//    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP);
//    writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber);
//    writeMessage(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
//    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP);
//  }

  /**
   * Write an unparsed MessageSet extension field to the stream.  For
   * historical reasons, the wire format differs from normal fields.
   */
//  public void writeRawMessageSetExtension(final int fieldNumber,
//                                          final ByteStringMicro value)
//                                          throws IOException {
//    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP);
//    writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber);
//    writeBytes(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
//    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP);
//  }

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

  /** Write a {@code double} field to the stream. */
  public void writeDoubleNoTag(final double value) throws IOException {
    writeRawLittleEndian64(Double.doubleToLongBits(value));
  }

  /** Write a {@code float} field to the stream. */
  public void writeFloatNoTag(final float value) throws IOException {
    writeRawLittleEndian32(Float.floatToIntBits(value));
  }

  /** Write a {@code uint64} field to the stream. */
  public void writeUInt64NoTag(final long value) throws IOException {
    writeRawVarint64(value);
  }

  /** Write an {@code int64} field to the stream. */
  public void writeInt64NoTag(final long value) throws IOException {
    writeRawVarint64(value);
  }

  /** Write an {@code int32} field to the stream. */
  public void writeInt32NoTag(final int value) throws IOException {
    if (value >= 0) {
      writeRawVarint32(value);
    } else {
      // Must sign-extend.
      writeRawVarint64(value);
    }
  }

  /** Write a {@code fixed64} field to the stream. */
  public void writeFixed64NoTag(final long value) throws IOException {
    writeRawLittleEndian64(value);
  }

  /** Write a {@code fixed32} field to the stream. */
  public void writeFixed32NoTag(final int value) throws IOException {
    writeRawLittleEndian32(value);
  }

  /** Write a {@code bool} field to the stream. */
  public void writeBoolNoTag(final boolean value) throws IOException {
    writeRawByte(value ? 1 : 0);
  }

  /** Write a {@code string} field to the stream. */
  public void writeStringNoTag(final String value) throws IOException {
    // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
    // and at most 3 times of it. Optimize for the case where we know this length results in a
    // constant varint length - saves measuring length of the string.
    try {
      final int minLengthVarIntSize = computeRawVarint32Size(value.length());
      final int maxLengthVarIntSize = computeRawVarint32Size(value.length() * MAX_UTF8_EXPANSION);
      if (minLengthVarIntSize == maxLengthVarIntSize) {
        int oldPosition = buffer.position();
        // Buffer.position, when passed a position that is past its limit, throws
        // IllegalArgumentException, and this class is documented to throw
        // OutOfSpaceException instead.
        if (buffer.remaining() < minLengthVarIntSize) {
          throw new OutOfSpaceException(oldPosition + minLengthVarIntSize, buffer.limit());
        }
        buffer.position(oldPosition + minLengthVarIntSize);
        encode(value, buffer);
        int newPosition = buffer.position();
        buffer.position(oldPosition);
        writeRawVarint32(newPosition - oldPosition - minLengthVarIntSize);
        buffer.position(newPosition);
      } else {
        writeRawVarint32(encodedLength(value));
        encode(value, buffer);
      }
    } catch (BufferOverflowException e) {
      final OutOfSpaceException outOfSpaceException = new OutOfSpaceException(buffer.position(),
          buffer.limit());
      outOfSpaceException.initCause(e);
      throw outOfSpaceException;
    }
  }

  // These UTF-8 handling methods are copied from Guava's Utf8 class.
  /**
   * Returns the number of bytes in the UTF-8-encoded form of {@code sequence}. For a string,
   * this method is equivalent to {@code string.getBytes(UTF_8).length}, but is more efficient in
   * both time and space.
   *
   * @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
   *     surrogates)
   */
  private static int encodedLength(CharSequence sequence) {
    // Warning to maintainers: this implementation is highly optimized.
    int utf16Length = sequence.length();
    int utf8Length = utf16Length;
    int i = 0;

    // This loop optimizes for pure ASCII.
    while (i < utf16Length && sequence.charAt(i) < 0x80) {
      i++;
    }

    // This loop optimizes for chars less than 0x800.
    for (; i < utf16Length; i++) {
      char c = sequence.charAt(i);
      if (c < 0x800) {
        utf8Length += ((0x7f - c) >>> 31);  // branch free!
      } else {
        utf8Length += encodedLengthGeneral(sequence, i);
        break;
      }
    }

    if (utf8Length < utf16Length) {
      // Necessary and sufficient condition for overflow because of maximum 3x expansion
      throw new IllegalArgumentException("UTF-8 length does not fit in int: "
              + (utf8Length + (1L << 32)));
    }
    return utf8Length;
  }

  private static int encodedLengthGeneral(CharSequence sequence, int start) {
    int utf16Length = sequence.length();
    int utf8Length = 0;
    for (int i = start; i < utf16Length; i++) {
      char c = sequence.charAt(i);
      if (c < 0x800) {
        utf8Length += (0x7f - c) >>> 31; // branch free!
      } else {
        utf8Length += 2;
        // jdk7+: if (Character.isSurrogate(c)) {
        if (Character.MIN_SURROGATE <= c && c <= Character.MAX_SURROGATE) {
          // Check that we have a well-formed surrogate pair.
          int cp = Character.codePointAt(sequence, i);
          if (cp < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
            throw new IllegalArgumentException("Unpaired surrogate at index " + i);
          }
          i++;
        }
      }
    }
    return utf8Length;
  }

  /**
   * Encodes {@code sequence} into UTF-8, in {@code byteBuffer}. For a string, this method is
   * equivalent to {@code buffer.put(string.getBytes(UTF_8))}, but is more efficient in both time
   * and space. Bytes are written starting at the current position. This method requires paired
   * surrogates, and therefore does not support chunking.
   *
   * <p>To ensure sufficient space in the output buffer, either call {@link #encodedLength} to
   * compute the exact amount needed, or leave room for {@code 3 * sequence.length()}, which is the
   * largest possible number of bytes that any input can be encoded to.
   *
   * @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
   *     surrogates)
   * @throws BufferOverflowException if {@code sequence} encoded in UTF-8 does not fit in
   *     {@code byteBuffer}'s remaining space.
   * @throws ReadOnlyBufferException if {@code byteBuffer} is a read-only buffer.
   */
  private static void encode(CharSequence sequence, ByteBuffer byteBuffer) {
    if (byteBuffer.isReadOnly()) {
      throw new ReadOnlyBufferException();
    } else if (byteBuffer.hasArray()) {
      try {
        int encoded = encode(sequence,
                byteBuffer.array(),
                byteBuffer.arrayOffset() + byteBuffer.position(),
                byteBuffer.remaining());
        byteBuffer.position(encoded - byteBuffer.arrayOffset());
      } catch (ArrayIndexOutOfBoundsException e) {
        BufferOverflowException boe = new BufferOverflowException();
        boe.initCause(e);
        throw boe;
      }
    } else {
      encodeDirect(sequence, byteBuffer);
    }
  }

  private static void encodeDirect(CharSequence sequence, ByteBuffer byteBuffer) {
    int utf16Length = sequence.length();
    for (int i = 0; i < utf16Length; i++) {
      final char c = sequence.charAt(i);
      if (c < 0x80) { // ASCII
        byteBuffer.put((byte) c);
      } else if (c < 0x800) { // 11 bits, two UTF-8 bytes
        byteBuffer.put((byte) ((0xF << 6) | (c >>> 6)));
        byteBuffer.put((byte) (0x80 | (0x3F & c)));
      } else if (c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c) {
        // Maximium single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
        byteBuffer.put((byte) ((0xF << 5) | (c >>> 12)));
        byteBuffer.put((byte) (0x80 | (0x3F & (c >>> 6))));
        byteBuffer.put((byte) (0x80 | (0x3F & c)));
      } else {
        final char low;
        if (i + 1 == sequence.length()
                || !Character.isSurrogatePair(c, (low = sequence.charAt(++i)))) {
          throw new IllegalArgumentException("Unpaired surrogate at index " + (i - 1));
        }
        int codePoint = Character.toCodePoint(c, low);
        byteBuffer.put((byte) ((0xF << 4) | (codePoint >>> 18)));
        byteBuffer.put((byte) (0x80 | (0x3F & (codePoint >>> 12))));
        byteBuffer.put((byte) (0x80 | (0x3F & (codePoint >>> 6))));
        byteBuffer.put((byte) (0x80 | (0x3F & codePoint)));
      }
    }
  }

  private static int encode(CharSequence sequence, byte[] bytes, int offset, int length) {
    int utf16Length = sequence.length();
    int j = offset;
    int i = 0;
    int limit = offset + length;
    // Designed to take advantage of
    // https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination
    for (char c; i < utf16Length && i + j < limit && (c = sequence.charAt(i)) < 0x80; i++) {
      bytes[j + i] = (byte) c;
    }
    if (i == utf16Length) {
      return j + utf16Length;
    }
    j += i;
    for (char c; i < utf16Length; i++) {
      c = sequence.charAt(i);
      if (c < 0x80 && j < limit) {
        bytes[j++] = (byte) c;
      } else if (c < 0x800 && j <= limit - 2) { // 11 bits, two UTF-8 bytes
        bytes[j++] = (byte) ((0xF << 6) | (c >>> 6));
        bytes[j++] = (byte) (0x80 | (0x3F & c));
      } else if ((c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c) && j <= limit - 3) {
        // Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
        bytes[j++] = (byte) ((0xF << 5) | (c >>> 12));
        bytes[j++] = (byte) (0x80 | (0x3F & (c >>> 6)));
        bytes[j++] = (byte) (0x80 | (0x3F & c));
      } else if (j <= limit - 4) {
        // Minimum code point represented by a surrogate pair is 0x10000, 17 bits, four UTF-8 bytes
        final char low;
        if (i + 1 == sequence.length()
                || !Character.isSurrogatePair(c, (low = sequence.charAt(++i)))) {
          throw new IllegalArgumentException("Unpaired surrogate at index " + (i - 1));
        }
        int codePoint = Character.toCodePoint(c, low);
        bytes[j++] = (byte) ((0xF << 4) | (codePoint >>> 18));
        bytes[j++] = (byte) (0x80 | (0x3F & (codePoint >>> 12)));
        bytes[j++] = (byte) (0x80 | (0x3F & (codePoint >>> 6)));
        bytes[j++] = (byte) (0x80 | (0x3F & codePoint));
      } else {
        throw new ArrayIndexOutOfBoundsException("Failed writing " + c + " at index " + j);
      }
    }
    return j;
  }

  // End guava UTF-8 methods


  /** Write a {@code group} field to the stream. */
  public void writeGroupNoTag(final MessageNano value) throws IOException {
    value.writeTo(this);
  }

  /** Write an embedded message field to the stream. */
  public void writeMessageNoTag(final MessageNano value) throws IOException {
    writeRawVarint32(value.getCachedSize());
    value.writeTo(this);
  }

  /** Write a {@code bytes} field to the stream. */
  public void writeBytesNoTag(final byte[] value) throws IOException {
    writeRawVarint32(value.length);
    writeRawBytes(value);
  }

  /** Write a {@code bytes} field to the stream. */
  public void writeBytesNoTag(final byte[] value, final int offset, final int length)
                              throws IOException {
    writeRawVarint32(length);
    writeRawBytes(value, offset, length);
  }

  /** Write a {@code uint32} field to the stream. */
  public void writeUInt32NoTag(final int value) throws IOException {
    writeRawVarint32(value);
  }

  /**
   * Write an enum field to the stream.  Caller is responsible
   * for converting the enum value to its numeric value.
   */
  public void writeEnumNoTag(final int value) throws IOException {
    writeRawVarint32(value);
  }

  /** Write an {@code sfixed32} field to the stream. */
  public void writeSFixed32NoTag(final int value) throws IOException {
    writeRawLittleEndian32(value);
  }

  /** Write an {@code sfixed64} field to the stream. */
  public void writeSFixed64NoTag(final long value) throws IOException {
    writeRawLittleEndian64(value);
  }

  /** Write an {@code sint32} field to the stream. */
  public void writeSInt32NoTag(final int value) throws IOException {
    writeRawVarint32(encodeZigZag32(value));
  }

  /** Write an {@code sint64} field to the stream. */
  public void writeSInt64NoTag(final long value) throws IOException {
    writeRawVarint64(encodeZigZag64(value));
  }

  // =================================================================

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code double} field, including tag.
   */
  public static int computeDoubleSize(final int fieldNumber,
                                      final double value) {
    return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code float} field, including tag.
   */
  public static int computeFloatSize(final int fieldNumber, final float value) {
    return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code uint64} field, including tag.
   */
  public static int computeUInt64Size(final int fieldNumber, final long value) {
    return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode an
   * {@code int64} field, including tag.
   */
  public static int computeInt64Size(final int fieldNumber, final long value) {
    return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode an
   * {@code int32} field, including tag.
   */
  public static int computeInt32Size(final int fieldNumber, final int value) {
    return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code fixed64} field, including tag.
   */
  public static int computeFixed64Size(final int fieldNumber,
                                       final long value) {
    return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code fixed32} field, including tag.
   */
  public static int computeFixed32Size(final int fieldNumber,
                                       final int value) {
    return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code bool} field, including tag.
   */
  public static int computeBoolSize(final int fieldNumber,
                                    final boolean value) {
    return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code string} field, including tag.
   */
  public static int computeStringSize(final int fieldNumber,
                                      final String value) {
    return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code group} field, including tag.
   */
  public static int computeGroupSize(final int fieldNumber,
                                     final MessageNano value) {
    return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode an
   * embedded message field, including tag.
   */
  public static int computeMessageSize(final int fieldNumber,
                                       final MessageNano value) {
    return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code bytes} field, including tag.
   */
  public static int computeBytesSize(final int fieldNumber,
                                     final byte[] value) {
    return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code bytes} field of the given length, including tag.
   */
  public static int computeBytesSize(final int fieldNumber,
                                     final int length) {
    return computeTagSize(fieldNumber) + computeBytesSizeNoTag(length);
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code uint32} field, including tag.
   */
  public static int computeUInt32Size(final int fieldNumber, final int value) {
    return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode an
   * enum field, including tag.  Caller is responsible for converting the
   * enum value to its numeric value.
   */
  public static int computeEnumSize(final int fieldNumber, final int value) {
    return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode an
   * {@code sfixed32} field, including tag.
   */
  public static int computeSFixed32Size(final int fieldNumber,
                                        final int value) {
    return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode an
   * {@code sfixed64} field, including tag.
   */
  public static int computeSFixed64Size(final int fieldNumber,
                                        final long value) {
    return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode an
   * {@code sint32} field, including tag.
   */
  public static int computeSInt32Size(final int fieldNumber, final int value) {
    return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode an
   * {@code sint64} field, including tag.
   */
  public static int computeSInt64Size(final int fieldNumber, final long value) {
    return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * MessageSet extension to the stream.  For historical reasons,
   * the wire format differs from normal fields.
   */
//  public static int computeMessageSetExtensionSize(
//      final int fieldNumber, final MessageMicro value) {
//    return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 +
//           computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) +
//           computeMessageSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
//  }

  /**
   * Compute the number of bytes that would be needed to encode an
   * unparsed MessageSet extension field to the stream.  For
   * historical reasons, the wire format differs from normal fields.
   */
//  public static int computeRawMessageSetExtensionSize(
//      final int fieldNumber, final ByteStringMicro value) {
//    return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 +
//           computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) +
//           computeBytesSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
//  }

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

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code double} field, including tag.
   */
  public static int computeDoubleSizeNoTag(final double value) {
    return LITTLE_ENDIAN_64_SIZE;
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code float} field, including tag.
   */
  public static int computeFloatSizeNoTag(final float value) {
    return LITTLE_ENDIAN_32_SIZE;
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code uint64} field, including tag.
   */
  public static int computeUInt64SizeNoTag(final long value) {
    return computeRawVarint64Size(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode an
   * {@code int64} field, including tag.
   */
  public static int computeInt64SizeNoTag(final long value) {
    return computeRawVarint64Size(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode an
   * {@code int32} field, including tag.
   */
  public static int computeInt32SizeNoTag(final int value) {
    if (value >= 0) {
      return computeRawVarint32Size(value);
    } else {
      // Must sign-extend.
      return 10;
    }
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code fixed64} field.
   */
  public static int computeFixed64SizeNoTag(final long value) {
    return LITTLE_ENDIAN_64_SIZE;
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code fixed32} field.
   */
  public static int computeFixed32SizeNoTag(final int value) {
    return LITTLE_ENDIAN_32_SIZE;
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code bool} field.
   */
  public static int computeBoolSizeNoTag(final boolean value) {
    return 1;
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code string} field.
   */
  public static int computeStringSizeNoTag(final String value) {
    final int length = encodedLength(value);
    return computeRawVarint32Size(length) + length;
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code group} field.
   */
  public static int computeGroupSizeNoTag(final MessageNano value) {
    return value.getSerializedSize();
  }

  /**
   * Compute the number of bytes that would be needed to encode an embedded
   * message field.
   */
  public static int computeMessageSizeNoTag(final MessageNano value) {
    final int size = value.getSerializedSize();
    return computeRawVarint32Size(size) + size;
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code bytes} field.
   */
  public static int computeBytesSizeNoTag(final byte[] value) {
    return computeRawVarint32Size(value.length) + value.length;
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code bytes} field of the given length.
   */
  public static int computeBytesSizeNoTag(final int length) {
    return computeRawVarint32Size(length) + length;
  }

  /**
   * Compute the number of bytes that would be needed to encode a
   * {@code uint32} field.
   */
  public static int computeUInt32SizeNoTag(final int value) {
    return computeRawVarint32Size(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode an enum field.
   * Caller is responsible for converting the enum value to its numeric value.
   */
  public static int computeEnumSizeNoTag(final int value) {
    return computeRawVarint32Size(value);
  }

  /**
   * Compute the number of bytes that would be needed to encode an
   * {@code sfixed32} field.
   */
  public static int computeSFixed32SizeNoTag(final int value) {
    return LITTLE_ENDIAN_32_SIZE;
  }

  /**
   * Compute the number of bytes that would be needed to encode an
   * {@code sfixed64} field.
   */
  public static int computeSFixed64SizeNoTag(final long value) {
    return LITTLE_ENDIAN_64_SIZE;
  }

  /**
   * Compute the number of bytes that would be needed to encode an
   * {@code sint32} field.
   */
  public static int computeSInt32SizeNoTag(final int value) {
    return computeRawVarint32Size(encodeZigZag32(value));
  }

  /**
   * Compute the number of bytes that would be needed to encode an
   * {@code sint64} field.
   */
  public static int computeSInt64SizeNoTag(final long value) {
    return computeRawVarint64Size(encodeZigZag64(value));
  }

  // =================================================================

  /**
   * If writing to a flat array, return the space left in the array.
   * Otherwise, throws {@code UnsupportedOperationException}.
   */
  public int spaceLeft() {
    return buffer.remaining();
  }

  /**
   * Verifies that {@link #spaceLeft()} returns zero.  It's common to create
   * a byte array that is exactly big enough to hold a message, then write to
   * it with a {@code CodedOutputStream}.  Calling {@code checkNoSpaceLeft()}
   * after writing verifies that the message was actually as big as expected,
   * which can help catch bugs.
   */
  public void checkNoSpaceLeft() {
    if (spaceLeft() != 0) {
      throw new IllegalStateException(
        "Did not write as much data as expected.");
    }
  }

  /**
   * Returns the position within the internal buffer.
   */
  public int position() {
    return buffer.position();
  }

  /**
   * Resets the position within the internal buffer to zero.
   *
   * @see #position
   * @see #spaceLeft
   */
  public void reset() {
    buffer.clear();
  }

  /**
   * If you create a CodedOutputStream around a simple flat array, you must
   * not attempt to write more bytes than the array has space.  Otherwise,
   * this exception will be thrown.
   */
  public static class OutOfSpaceException extends IOException {
    private static final long serialVersionUID = -6947486886997889499L;

    OutOfSpaceException(int position, int limit) {
      super("CodedOutputStream was writing to a flat byte array and ran " +
            "out of space (pos " + position + " limit " + limit + ").");
    }
  }

  /** Write a single byte. */
  public void writeRawByte(final byte value) throws IOException {
    if (!buffer.hasRemaining()) {
      // We're writing to a single buffer.
      throw new OutOfSpaceException(buffer.position(), buffer.limit());
    }

    buffer.put(value);
  }

  /** Write a single byte, represented by an integer value. */
  public void writeRawByte(final int value) throws IOException {
    writeRawByte((byte) value);
  }

  /** Write an array of bytes. */
  public void writeRawBytes(final byte[] value) throws IOException {
    writeRawBytes(value, 0, value.length);
  }

  /** Write part of an array of bytes. */
  public void writeRawBytes(final byte[] value, int offset, int length)
                            throws IOException {
    if (buffer.remaining() >= length) {
      buffer.put(value, offset, length);
    } else {
      // We're writing to a single buffer.
      throw new OutOfSpaceException(buffer.position(), buffer.limit());
    }
  }

  /** Encode and write a tag. */
  public void writeTag(final int fieldNumber, final int wireType)
                       throws IOException {
    writeRawVarint32(WireFormatNano.makeTag(fieldNumber, wireType));
  }

  /** Compute the number of bytes that would be needed to encode a tag. */
  public static int computeTagSize(final int fieldNumber) {
    return computeRawVarint32Size(WireFormatNano.makeTag(fieldNumber, 0));
  }

  /**
   * Encode and write a varint.  {@code value} is treated as
   * unsigned, so it won't be sign-extended if negative.
   */
  public void writeRawVarint32(int value) throws IOException {
    while (true) {
      if ((value & ~0x7F) == 0) {
        writeRawByte(value);
        return;
      } else {
        writeRawByte((value & 0x7F) | 0x80);
        value >>>= 7;
      }
    }
  }

  /**
   * Compute the number of bytes that would be needed to encode a varint.
   * {@code value} is treated as unsigned, so it won't be sign-extended if
   * negative.
   */
  public static int computeRawVarint32Size(final int value) {
    if ((value & (0xffffffff <<  7)) == 0) return 1;
    if ((value & (0xffffffff << 14)) == 0) return 2;
    if ((value & (0xffffffff << 21)) == 0) return 3;
    if ((value & (0xffffffff << 28)) == 0) return 4;
    return 5;
  }

  /** Encode and write a varint. */
  public void writeRawVarint64(long value) throws IOException {
    while (true) {
      if ((value & ~0x7FL) == 0) {
        writeRawByte((int)value);
        return;
      } else {
        writeRawByte(((int)value & 0x7F) | 0x80);
        value >>>= 7;
      }
    }
  }

  /** Compute the number of bytes that would be needed to encode a varint. */
  public static int computeRawVarint64Size(final long value) {
    if ((value & (0xffffffffffffffffL <<  7)) == 0) return 1;
    if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
    if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
    if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
    if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
    if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
    if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
    if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
    if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
    return 10;
  }

  /** Write a little-endian 32-bit integer. */
  public void writeRawLittleEndian32(final int value) throws IOException {
    if (buffer.remaining() < 4) {
      throw new OutOfSpaceException(buffer.position(), buffer.limit());
    }
    buffer.putInt(value);
  }

  public static final int LITTLE_ENDIAN_32_SIZE = 4;

  /** Write a little-endian 64-bit integer. */
  public void writeRawLittleEndian64(final long value) throws IOException {
    if (buffer.remaining() < 8) {
      throw new OutOfSpaceException(buffer.position(), buffer.limit());
    }
    buffer.putLong(value);
  }

  public static final int LITTLE_ENDIAN_64_SIZE = 8;

  /**
   * Encode a ZigZag-encoded 32-bit value.  ZigZag encodes signed integers
   * into values that can be efficiently encoded with varint.  (Otherwise,
   * negative values must be sign-extended to 64 bits to be varint encoded,
   * thus always taking 10 bytes on the wire.)
   *
   * @param n A signed 32-bit integer.
   * @return An unsigned 32-bit integer, stored in a signed int because
   *         Java has no explicit unsigned support.
   */
  public static int encodeZigZag32(final int n) {
    // Note:  the right-shift must be arithmetic
    return (n << 1) ^ (n >> 31);
  }

  /**
   * Encode a ZigZag-encoded 64-bit value.  ZigZag encodes signed integers
   * into values that can be efficiently encoded with varint.  (Otherwise,
   * negative values must be sign-extended to 64 bits to be varint encoded,
   * thus always taking 10 bytes on the wire.)
   *
   * @param n A signed 64-bit integer.
   * @return An unsigned 64-bit integer, stored in a signed int because
   *         Java has no explicit unsigned support.
   */
  public static long encodeZigZag64(final long n) {
    // Note:  the right-shift must be arithmetic
    return (n << 1) ^ (n >> 63);
  }

  static int computeFieldSize(int number, int type, Object object) {
    switch (type) {
      case InternalNano.TYPE_BOOL:
        return computeBoolSize(number, (Boolean) object);
      case InternalNano.TYPE_BYTES:
        return computeBytesSize(number, (byte[]) object);
      case InternalNano.TYPE_STRING:
        return computeStringSize(number, (String) object);
      case InternalNano.TYPE_FLOAT:
        return computeFloatSize(number, (Float) object);
      case InternalNano.TYPE_DOUBLE:
        return computeDoubleSize(number, (Double) object);
      case InternalNano.TYPE_ENUM:
        return computeEnumSize(number, (Integer) object);
      case InternalNano.TYPE_FIXED32:
        return computeFixed32Size(number, (Integer) object);
      case InternalNano.TYPE_INT32:
        return computeInt32Size(number, (Integer) object);
      case InternalNano.TYPE_UINT32:
        return computeUInt32Size(number, (Integer) object);
      case InternalNano.TYPE_SINT32:
        return computeSInt32Size(number, (Integer) object);
      case InternalNano.TYPE_SFIXED32:
        return computeSFixed32Size(number, (Integer) object);
      case InternalNano.TYPE_INT64:
        return computeInt64Size(number, (Long) object);
      case InternalNano.TYPE_UINT64:
        return computeUInt64Size(number, (Long) object);
      case InternalNano.TYPE_SINT64:
        return computeSInt64Size(number, (Long) object);
      case InternalNano.TYPE_FIXED64:
        return computeFixed64Size(number, (Long) object);
      case InternalNano.TYPE_SFIXED64:
        return computeSFixed64Size(number, (Long) object);
      case InternalNano.TYPE_MESSAGE:
        return computeMessageSize(number, (MessageNano) object);
      case InternalNano.TYPE_GROUP:
        return computeGroupSize(number, (MessageNano) object);
      default:
        throw new IllegalArgumentException("Unknown type: " + type);
    }
  }

  void writeField(int number, int type, Object value)
      throws IOException {
    switch (type) {
      case InternalNano.TYPE_DOUBLE:
        Double doubleValue = (Double) value;
        writeDouble(number, doubleValue);
        break;
      case InternalNano.TYPE_FLOAT:
        Float floatValue = (Float) value;
        writeFloat(number, floatValue);
        break;
      case InternalNano.TYPE_INT64:
        Long int64Value = (Long) value;
        writeInt64(number, int64Value);
        break;
      case InternalNano.TYPE_UINT64:
        Long uint64Value = (Long) value;
        writeUInt64(number, uint64Value);
        break;
      case InternalNano.TYPE_INT32:
        Integer int32Value = (Integer) value;
        writeInt32(number, int32Value);
        break;
      case InternalNano.TYPE_FIXED64:
        Long fixed64Value = (Long) value;
        writeFixed64(number, fixed64Value);
        break;
      case InternalNano.TYPE_FIXED32:
        Integer fixed32Value = (Integer) value;
        writeFixed32(number, fixed32Value);
        break;
      case InternalNano.TYPE_BOOL:
        Boolean boolValue = (Boolean) value;
        writeBool(number, boolValue);
        break;
      case InternalNano.TYPE_STRING:
        String stringValue = (String) value;
        writeString(number, stringValue);
        break;
      case InternalNano.TYPE_BYTES:
        byte[] bytesValue = (byte[]) value;
        writeBytes(number, bytesValue);
        break;
      case InternalNano.TYPE_UINT32:
        Integer uint32Value = (Integer) value;
        writeUInt32(number, uint32Value);
        break;
      case InternalNano.TYPE_ENUM:
        Integer enumValue = (Integer) value;
        writeEnum(number, enumValue);
        break;
      case InternalNano.TYPE_SFIXED32:
        Integer sfixed32Value = (Integer) value;
        writeSFixed32(number, sfixed32Value);
        break;
      case InternalNano.TYPE_SFIXED64:
        Long sfixed64Value = (Long) value;
        writeSFixed64(number, sfixed64Value);
        break;
      case InternalNano.TYPE_SINT32:
        Integer sint32Value = (Integer) value;
        writeSInt32(number, sint32Value);
        break;
      case InternalNano.TYPE_SINT64:
        Long sint64Value = (Long) value;
        writeSInt64(number, sint64Value);
        break;
      case InternalNano.TYPE_MESSAGE:
        MessageNano messageValue = (MessageNano) value;
        writeMessage(number, messageValue);
        break;
      case InternalNano.TYPE_GROUP:
        MessageNano groupValue = (MessageNano) value;
        writeGroup(number, groupValue);
        break;
      default:
        throw new IOException("Unknown type: " + type);
    }
  }

}
