// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package com.google.protobuf;

import static com.google.protobuf.Internal.EMPTY_BYTE_ARRAY;
import static com.google.protobuf.Internal.EMPTY_BYTE_BUFFER;
import static com.google.protobuf.Internal.UTF_8;
import static com.google.protobuf.Internal.checkNotNull;
import static com.google.protobuf.WireFormat.FIXED32_SIZE;
import static com.google.protobuf.WireFormat.FIXED64_SIZE;
import static com.google.protobuf.WireFormat.MAX_VARINT_SIZE;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 * Reads and decodes protocol message fields.
 *
 * <p>This class contains two kinds of methods: methods that read specific protocol message
 * constructs and field types (e.g. {@link #readTag()} and {@link #readInt32()}) and methods that
 * read low-level values (e.g. {@link #readRawVarint32()} and {@link #readRawBytes}). If you are
 * reading encoded protocol messages, you should use the former methods, but if you are reading some
 * other format of your own design, use the latter.
 *
 * @author kenton@google.com Kenton Varda
 */
public abstract class CodedInputStream {
  private static final int DEFAULT_BUFFER_SIZE = 4096;
  private static final int DEFAULT_RECURSION_LIMIT = 100;
  // Integer.MAX_VALUE == 0x7FFFFFF == INT_MAX from limits.h
  private static final int DEFAULT_SIZE_LIMIT = Integer.MAX_VALUE;

  /** Visible for subclasses. See setRecursionLimit() */
  int recursionDepth;

  int recursionLimit = DEFAULT_RECURSION_LIMIT;

  /** Visible for subclasses. See setSizeLimit() */
  int sizeLimit = DEFAULT_SIZE_LIMIT;

  /** Create a new CodedInputStream wrapping the given InputStream. */
  public static CodedInputStream newInstance(final InputStream input) {
    return newInstance(input, DEFAULT_BUFFER_SIZE);
  }

  /** Create a new CodedInputStream wrapping the given InputStream, with a specified buffer size. */
  public static CodedInputStream newInstance(final InputStream input, int bufferSize) {
    if (bufferSize <= 0) {
      throw new IllegalArgumentException("bufferSize must be > 0");
    }
    if (input == null) {
      // TODO(nathanmittler): Ideally we should throw here. This is done for backward compatibility.
      return newInstance(EMPTY_BYTE_ARRAY);
    }
    return new StreamDecoder(input, bufferSize);
  }

  /** Create a new CodedInputStream wrapping the given {@code Iterable <ByteBuffer>}. */
  public static CodedInputStream newInstance(final Iterable<ByteBuffer> input) {
    if (!UnsafeDirectNioDecoder.isSupported()) {
      return newInstance(new IterableByteBufferInputStream(input));
    }
    return newInstance(input, false);
  }

  /** Create a new CodedInputStream wrapping the given {@code Iterable <ByteBuffer>}. */
  static CodedInputStream newInstance(
      final Iterable<ByteBuffer> bufs, final boolean bufferIsImmutable) {
    // flag is to check the type of input's ByteBuffers.
    // flag equals 1: all ByteBuffers have array.
    // flag equals 2: all ByteBuffers are direct ByteBuffers.
    // flag equals 3: some ByteBuffers are direct and some have array.
    // flag greater than 3: other cases.
    int flag = 0;
    // Total size of the input
    int totalSize = 0;
    for (ByteBuffer buf : bufs) {
      totalSize += buf.remaining();
      if (buf.hasArray()) {
        flag |= 1;
      } else if (buf.isDirect()) {
        flag |= 2;
      } else {
        flag |= 4;
      }
    }
    if (flag == 2) {
      return new IterableDirectByteBufferDecoder(bufs, totalSize, bufferIsImmutable);
    } else {
      // TODO(yilunchong): add another decoders to deal case 1 and 3.
      return newInstance(new IterableByteBufferInputStream(bufs));
    }
  }

  /** Create a new CodedInputStream wrapping the given byte array. */
  public static CodedInputStream newInstance(final byte[] buf) {
    return newInstance(buf, 0, buf.length);
  }

  /** Create a new CodedInputStream wrapping the given byte array slice. */
  public static CodedInputStream newInstance(final byte[] buf, final int off, final int len) {
    return newInstance(buf, off, len, /* bufferIsImmutable= */ false);
  }

  /** Create a new CodedInputStream wrapping the given byte array slice. */
  static CodedInputStream newInstance(
      final byte[] buf, final int off, final int len, final boolean bufferIsImmutable) {
    ArrayDecoder result = new ArrayDecoder(buf, off, len, bufferIsImmutable);
    try {
      // Some uses of CodedInputStream can be more efficient if they know
      // exactly how many bytes are available.  By pushing the end point of the
      // buffer as a limit, we allow them to get this information via
      // getBytesUntilLimit().  Pushing a limit that we know is at the end of
      // the stream can never hurt, since we can never past that point anyway.
      result.pushLimit(len);
    } catch (InvalidProtocolBufferException ex) {
      // The only reason pushLimit() might throw an exception here is if len
      // is negative. Normally pushLimit()'s parameter comes directly off the
      // wire, so it's important to catch exceptions in case of corrupt or
      // malicious data. However, in this case, we expect that len is not a
      // user-supplied value, so we can assume that it being negative indicates
      // a programming error. Therefore, throwing an unchecked exception is
      // appropriate.
      throw new IllegalArgumentException(ex);
    }
    return result;
  }

  /**
   * Create a new CodedInputStream wrapping the given ByteBuffer. The data starting from the
   * ByteBuffer's current position to its limit will be read. The returned CodedInputStream may or
   * may not share the underlying data in the ByteBuffer, therefore the ByteBuffer cannot be changed
   * while the CodedInputStream is in use. Note that the ByteBuffer's position won't be changed by
   * this function. Concurrent calls with the same ByteBuffer object are safe if no other thread is
   * trying to alter the ByteBuffer's status.
   */
  public static CodedInputStream newInstance(ByteBuffer buf) {
    return newInstance(buf, /* bufferIsImmutable= */ false);
  }

  /** Create a new CodedInputStream wrapping the given buffer. */
  static CodedInputStream newInstance(ByteBuffer buf, boolean bufferIsImmutable) {
    if (buf.hasArray()) {
      return newInstance(
          buf.array(), buf.arrayOffset() + buf.position(), buf.remaining(), bufferIsImmutable);
    }

    if (buf.isDirect() && UnsafeDirectNioDecoder.isSupported()) {
      return new UnsafeDirectNioDecoder(buf, bufferIsImmutable);
    }

    // The buffer is non-direct and does not expose the underlying array. Using the ByteBuffer API
    // to access individual bytes is very slow, so just copy the buffer to an array.
    // TODO(nathanmittler): Re-evaluate with Java 9
    byte[] buffer = new byte[buf.remaining()];
    buf.duplicate().get(buffer);
    return newInstance(buffer, 0, buffer.length, true);
  }

  /** Disable construction/inheritance outside of this class. */
  private CodedInputStream() {}

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

  /**
   * Attempt to read a field tag, returning zero if we have reached EOF. Protocol message parsers
   * use this to read tags, since a protocol message may legally end wherever a tag occurs, and zero
   * is not a valid tag number.
   */
  public abstract int readTag() throws IOException;

  /**
   * Verifies that the last call to readTag() returned the given tag value. This is used to verify
   * that a nested group ended with the correct end tag.
   *
   * @throws InvalidProtocolBufferException {@code value} does not match the last tag.
   */
  public abstract void checkLastTagWas(final int value) throws InvalidProtocolBufferException;

  public abstract int getLastTag();

  /**
   * Reads and discards a single field, given its tag value.
   *
   * @return {@code false} if the tag is an endgroup tag, in which case nothing is skipped.
   *     Otherwise, returns {@code true}.
   */
  public abstract boolean skipField(final int tag) throws IOException;

  /**
   * Reads a single field and writes it to output in wire format, given its tag value.
   *
   * @return {@code false} if the tag is an endgroup tag, in which case nothing is skipped.
   *     Otherwise, returns {@code true}.
   * @deprecated use {@code UnknownFieldSet} or {@code UnknownFieldSetLite} to skip to an output
   *     stream.
   */
  @Deprecated
  public abstract boolean skipField(final int tag, final CodedOutputStream output)
      throws IOException;

  /**
   * Reads and discards an entire message. This will read either until EOF or until an endgroup tag,
   * whichever comes first.
   */
  public abstract void skipMessage() throws IOException;

  /**
   * Reads an entire message and writes it to output in wire format. This will read either until EOF
   * or until an endgroup tag, whichever comes first.
   */
  public abstract void skipMessage(CodedOutputStream output) throws IOException;


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

  /** Read a {@code double} field value from the stream. */
  public abstract double readDouble() throws IOException;

  /** Read a {@code float} field value from the stream. */
  public abstract float readFloat() throws IOException;

  /** Read a {@code uint64} field value from the stream. */
  public abstract long readUInt64() throws IOException;

  /** Read an {@code int64} field value from the stream. */
  public abstract long readInt64() throws IOException;

  /** Read an {@code int32} field value from the stream. */
  public abstract int readInt32() throws IOException;

  /** Read a {@code fixed64} field value from the stream. */
  public abstract long readFixed64() throws IOException;

  /** Read a {@code fixed32} field value from the stream. */
  public abstract int readFixed32() throws IOException;

  /** Read a {@code bool} field value from the stream. */
  public abstract boolean readBool() throws IOException;

  /**
   * Read a {@code string} field value from the stream. If the stream contains malformed UTF-8,
   * replace the offending bytes with the standard UTF-8 replacement character.
   */
  public abstract String readString() throws IOException;

  /**
   * Read a {@code string} field value from the stream. If the stream contains malformed UTF-8,
   * throw exception {@link InvalidProtocolBufferException}.
   */
  public abstract String readStringRequireUtf8() throws IOException;

  /** Read a {@code group} field value from the stream. */
  public abstract void readGroup(
      final int fieldNumber,
      final MessageLite.Builder builder,
      final ExtensionRegistryLite extensionRegistry)
      throws IOException;


  /** Read a {@code group} field value from the stream. */
  public abstract <T extends MessageLite> T readGroup(
      final int fieldNumber, final Parser<T> parser, final ExtensionRegistryLite extensionRegistry)
      throws IOException;

  /**
   * Reads a {@code group} field value from the stream and merges it into the given {@link
   * UnknownFieldSet}.
   *
   * @deprecated UnknownFieldSet.Builder now implements MessageLite.Builder, so you can just call
   *     {@link #readGroup}.
   */
  @Deprecated
  public abstract void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
      throws IOException;

  /** Read an embedded message field value from the stream. */
  public abstract void readMessage(
      final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
      throws IOException;


  /** Read an embedded message field value from the stream. */
  public abstract <T extends MessageLite> T readMessage(
      final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException;

  /** Read a {@code bytes} field value from the stream. */
  public abstract ByteString readBytes() throws IOException;

  /** Read a {@code bytes} field value from the stream. */
  public abstract byte[] readByteArray() throws IOException;

  /** Read a {@code bytes} field value from the stream. */
  public abstract ByteBuffer readByteBuffer() throws IOException;

  /** Read a {@code uint32} field value from the stream. */
  public abstract int readUInt32() throws IOException;

  /**
   * Read an enum field value from the stream. Caller is responsible for converting the numeric
   * value to an actual enum.
   */
  public abstract int readEnum() throws IOException;

  /** Read an {@code sfixed32} field value from the stream. */
  public abstract int readSFixed32() throws IOException;

  /** Read an {@code sfixed64} field value from the stream. */
  public abstract long readSFixed64() throws IOException;

  /** Read an {@code sint32} field value from the stream. */
  public abstract int readSInt32() throws IOException;

  /** Read an {@code sint64} field value from the stream. */
  public abstract long readSInt64() throws IOException;

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

  /** Read a raw Varint from the stream. If larger than 32 bits, discard the upper bits. */
  public abstract int readRawVarint32() throws IOException;

  /** Read a raw Varint from the stream. */
  public abstract long readRawVarint64() throws IOException;

  /** Variant of readRawVarint64 for when uncomfortably close to the limit. */
  /* Visible for testing */
  abstract long readRawVarint64SlowPath() throws IOException;

  /** Read a 32-bit little-endian integer from the stream. */
  public abstract int readRawLittleEndian32() throws IOException;

  /** Read a 64-bit little-endian integer from the stream. */
  public abstract long readRawLittleEndian64() throws IOException;

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

  /**
   * Enables {@link ByteString} aliasing of the underlying buffer, trading off on buffer pinning for
   * data copies. Only valid for buffer-backed streams.
   */
  public abstract void enableAliasing(boolean enabled);

  /**
   * Set the maximum message recursion depth. In order to prevent malicious messages from causing
   * stack overflows, {@code CodedInputStream} limits how deeply messages may be nested. The default
   * limit is 100.
   *
   * @return the old limit.
   */
  public final int setRecursionLimit(final int limit) {
    if (limit < 0) {
      throw new IllegalArgumentException("Recursion limit cannot be negative: " + limit);
    }
    final int oldLimit = recursionLimit;
    recursionLimit = limit;
    return oldLimit;
  }

  /**
   * Only valid for {@link InputStream}-backed streams.
   *
   * <p>Set the maximum message size. In order to prevent malicious messages from exhausting memory
   * or causing integer overflows, {@code CodedInputStream} limits how large a message may be. The
   * default limit is {@code Integer.MAX_INT}. You should set this limit as small as you can without
   * harming your app's functionality. Note that size limits only apply when reading from an {@code
   * InputStream}, not when constructed around a raw byte array.
   *
   * <p>If you want to read several messages from a single CodedInputStream, you could call {@link
   * #resetSizeCounter()} after each one to avoid hitting the size limit.
   *
   * @return the old limit.
   */
  public final int setSizeLimit(final int limit) {
    if (limit < 0) {
      throw new IllegalArgumentException("Size limit cannot be negative: " + limit);
    }
    final int oldLimit = sizeLimit;
    sizeLimit = limit;
    return oldLimit;
  }

  private boolean shouldDiscardUnknownFields = false;

  /**
   * Sets this {@code CodedInputStream} to discard unknown fields. Only applies to full runtime
   * messages; lite messages will always preserve unknowns.
   *
   * <p>Note calling this function alone will have NO immediate effect on the underlying input data.
   * The unknown fields will be discarded during parsing. This affects both Proto2 and Proto3 full
   * runtime.
   */
  final void discardUnknownFields() {
    shouldDiscardUnknownFields = true;
  }

  /**
   * Reverts the unknown fields preservation behavior for Proto2 and Proto3 full runtime to their
   * default.
   */
  final void unsetDiscardUnknownFields() {
    shouldDiscardUnknownFields = false;
  }

  /**
   * Whether unknown fields in this input stream should be discarded during parsing into full
   * runtime messages.
   */
  final boolean shouldDiscardUnknownFields() {
    return shouldDiscardUnknownFields;
  }

  /**
   * Resets the current size counter to zero (see {@link #setSizeLimit(int)}). Only valid for {@link
   * InputStream}-backed streams.
   */
  public abstract void resetSizeCounter();

  /**
   * Sets {@code currentLimit} to (current position) + {@code byteLimit}. This is called when
   * descending into a length-delimited embedded message.
   *
   * <p>Note that {@code pushLimit()} does NOT affect how many bytes the {@code CodedInputStream}
   * reads from an underlying {@code InputStream} when refreshing its buffer. If you need to prevent
   * reading past a certain point in the underlying {@code InputStream} (e.g. because you expect it
   * to contain more data after the end of the message which you need to handle differently) then
   * you must place a wrapper around your {@code InputStream} which limits the amount of data that
   * can be read from it.
   *
   * @return the old limit.
   */
  public abstract int pushLimit(int byteLimit) throws InvalidProtocolBufferException;

  /**
   * Discards the current limit, returning to the previous limit.
   *
   * @param oldLimit The old limit, as returned by {@code pushLimit}.
   */
  public abstract void popLimit(final int oldLimit);

  /**
   * Returns the number of bytes to be read before the current limit. If no limit is set, returns
   * -1.
   */
  public abstract int getBytesUntilLimit();

  /**
   * Returns true if the stream has reached the end of the input. This is the case if either the end
   * of the underlying input source has been reached or if the stream has reached a limit created
   * using {@link #pushLimit(int)}.
   */
  public abstract boolean isAtEnd() throws IOException;

  /**
   * The total bytes read up to the current position. Calling {@link #resetSizeCounter()} resets
   * this value to zero.
   */
  public abstract int getTotalBytesRead();

  /**
   * Read one byte from the input.
   *
   * @throws InvalidProtocolBufferException The end of the stream or the current limit was reached.
   */
  public abstract byte readRawByte() throws IOException;

  /**
   * Read a fixed size of bytes from the input.
   *
   * @throws InvalidProtocolBufferException The end of the stream or the current limit was reached.
   */
  public abstract byte[] readRawBytes(final int size) throws IOException;

  /**
   * Reads and discards {@code size} bytes.
   *
   * @throws InvalidProtocolBufferException The end of the stream or the current limit was reached.
   */
  public abstract void skipRawBytes(final int size) throws IOException;

  /**
   * Decode 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 An unsigned 32-bit integer, stored in a signed int because Java has no explicit
   *     unsigned support.
   * @return A signed 32-bit integer.
   */
  public static int decodeZigZag32(final int n) {
    return (n >>> 1) ^ -(n & 1);
  }

  /**
   * Decode 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 An unsigned 64-bit integer, stored in a signed int because Java has no explicit
   *     unsigned support.
   * @return A signed 64-bit integer.
   */
  public static long decodeZigZag64(final long n) {
    return (n >>> 1) ^ -(n & 1);
  }

  /**
   * Like {@link #readRawVarint32(InputStream)}, but expects that the caller has already read one
   * byte. This allows the caller to determine if EOF has been reached before attempting to read.
   */
  public static int readRawVarint32(final int firstByte, final InputStream input)
      throws IOException {
    if ((firstByte & 0x80) == 0) {
      return firstByte;
    }

    int result = firstByte & 0x7f;
    int offset = 7;
    for (; offset < 32; offset += 7) {
      final int b = input.read();
      if (b == -1) {
        throw InvalidProtocolBufferException.truncatedMessage();
      }
      result |= (b & 0x7f) << offset;
      if ((b & 0x80) == 0) {
        return result;
      }
    }
    // Keep reading up to 64 bits.
    for (; offset < 64; offset += 7) {
      final int b = input.read();
      if (b == -1) {
        throw InvalidProtocolBufferException.truncatedMessage();
      }
      if ((b & 0x80) == 0) {
        return result;
      }
    }
    throw InvalidProtocolBufferException.malformedVarint();
  }

  /**
   * Reads a varint from the input one byte at a time, so that it does not read any bytes after the
   * end of the varint. If you simply wrapped the stream in a CodedInputStream and used {@link
   * #readRawVarint32(InputStream)} then you would probably end up reading past the end of the
   * varint since CodedInputStream buffers its input.
   */
  static int readRawVarint32(final InputStream input) throws IOException {
    final int firstByte = input.read();
    if (firstByte == -1) {
      throw InvalidProtocolBufferException.truncatedMessage();
    }
    return readRawVarint32(firstByte, input);
  }

  /** A {@link CodedInputStream} implementation that uses a backing array as the input. */
  private static final class ArrayDecoder extends CodedInputStream {
    private final byte[] buffer;
    private final boolean immutable;
    private int limit;
    private int bufferSizeAfterLimit;
    private int pos;
    private int startPos;
    private int lastTag;
    private boolean enableAliasing;

    /** The absolute position of the end of the current message. */
    private int currentLimit = Integer.MAX_VALUE;

    private ArrayDecoder(final byte[] buffer, final int offset, final int len, boolean immutable) {
      this.buffer = buffer;
      limit = offset + len;
      pos = offset;
      startPos = pos;
      this.immutable = immutable;
    }

    @Override
    public int readTag() throws IOException {
      if (isAtEnd()) {
        lastTag = 0;
        return 0;
      }

      lastTag = readRawVarint32();
      if (WireFormat.getTagFieldNumber(lastTag) == 0) {
        // If we actually read zero (or any tag number corresponding to field
        // number zero), that's not a valid tag.
        throw InvalidProtocolBufferException.invalidTag();
      }
      return lastTag;
    }

    @Override
    public void checkLastTagWas(final int value) throws InvalidProtocolBufferException {
      if (lastTag != value) {
        throw InvalidProtocolBufferException.invalidEndTag();
      }
    }

    @Override
    public int getLastTag() {
      return lastTag;
    }

    @Override
    public boolean skipField(final int tag) throws IOException {
      switch (WireFormat.getTagWireType(tag)) {
        case WireFormat.WIRETYPE_VARINT:
          skipRawVarint();
          return true;
        case WireFormat.WIRETYPE_FIXED64:
          skipRawBytes(FIXED64_SIZE);
          return true;
        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
          skipRawBytes(readRawVarint32());
          return true;
        case WireFormat.WIRETYPE_START_GROUP:
          skipMessage();
          checkLastTagWas(
              WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
          return true;
        case WireFormat.WIRETYPE_END_GROUP:
          return false;
        case WireFormat.WIRETYPE_FIXED32:
          skipRawBytes(FIXED32_SIZE);
          return true;
        default:
          throw InvalidProtocolBufferException.invalidWireType();
      }
    }

    @Override
    public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
      switch (WireFormat.getTagWireType(tag)) {
        case WireFormat.WIRETYPE_VARINT:
          {
            long value = readInt64();
            output.writeRawVarint32(tag);
            output.writeUInt64NoTag(value);
            return true;
          }
        case WireFormat.WIRETYPE_FIXED64:
          {
            long value = readRawLittleEndian64();
            output.writeRawVarint32(tag);
            output.writeFixed64NoTag(value);
            return true;
          }
        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
          {
            ByteString value = readBytes();
            output.writeRawVarint32(tag);
            output.writeBytesNoTag(value);
            return true;
          }
        case WireFormat.WIRETYPE_START_GROUP:
          {
            output.writeRawVarint32(tag);
            skipMessage(output);
            int endtag =
                WireFormat.makeTag(
                    WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
            checkLastTagWas(endtag);
            output.writeRawVarint32(endtag);
            return true;
          }
        case WireFormat.WIRETYPE_END_GROUP:
          {
            return false;
          }
        case WireFormat.WIRETYPE_FIXED32:
          {
            int value = readRawLittleEndian32();
            output.writeRawVarint32(tag);
            output.writeFixed32NoTag(value);
            return true;
          }
        default:
          throw InvalidProtocolBufferException.invalidWireType();
      }
    }

    @Override
    public void skipMessage() throws IOException {
      while (true) {
        final int tag = readTag();
        if (tag == 0 || !skipField(tag)) {
          return;
        }
      }
    }

    @Override
    public void skipMessage(CodedOutputStream output) throws IOException {
      while (true) {
        final int tag = readTag();
        if (tag == 0 || !skipField(tag, output)) {
          return;
        }
      }
    }


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

    @Override
    public double readDouble() throws IOException {
      return Double.longBitsToDouble(readRawLittleEndian64());
    }

    @Override
    public float readFloat() throws IOException {
      return Float.intBitsToFloat(readRawLittleEndian32());
    }

    @Override
    public long readUInt64() throws IOException {
      return readRawVarint64();
    }

    @Override
    public long readInt64() throws IOException {
      return readRawVarint64();
    }

    @Override
    public int readInt32() throws IOException {
      return readRawVarint32();
    }

    @Override
    public long readFixed64() throws IOException {
      return readRawLittleEndian64();
    }

    @Override
    public int readFixed32() throws IOException {
      return readRawLittleEndian32();
    }

    @Override
    public boolean readBool() throws IOException {
      return readRawVarint64() != 0;
    }

    @Override
    public String readString() throws IOException {
      final int size = readRawVarint32();
      if (size > 0 && size <= (limit - pos)) {
        // Fast path:  We already have the bytes in a contiguous buffer, so
        //   just copy directly from it.
        final String result = new String(buffer, pos, size, UTF_8);
        pos += size;
        return result;
      }

      if (size == 0) {
        return "";
      }
      if (size < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      throw InvalidProtocolBufferException.truncatedMessage();
    }

    @Override
    public String readStringRequireUtf8() throws IOException {
      final int size = readRawVarint32();
      if (size > 0 && size <= (limit - pos)) {
        String result = Utf8.decodeUtf8(buffer, pos, size);
        pos += size;
        return result;
      }

      if (size == 0) {
        return "";
      }
      if (size <= 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      throw InvalidProtocolBufferException.truncatedMessage();
    }

    @Override
    public void readGroup(
        final int fieldNumber,
        final MessageLite.Builder builder,
        final ExtensionRegistryLite extensionRegistry)
        throws IOException {
      if (recursionDepth >= recursionLimit) {
        throw InvalidProtocolBufferException.recursionLimitExceeded();
      }
      ++recursionDepth;
      builder.mergeFrom(this, extensionRegistry);
      checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
      --recursionDepth;
    }


    @Override
    public <T extends MessageLite> T readGroup(
        final int fieldNumber,
        final Parser<T> parser,
        final ExtensionRegistryLite extensionRegistry)
        throws IOException {
      if (recursionDepth >= recursionLimit) {
        throw InvalidProtocolBufferException.recursionLimitExceeded();
      }
      ++recursionDepth;
      T result = parser.parsePartialFrom(this, extensionRegistry);
      checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
      --recursionDepth;
      return result;
    }

    @Deprecated
    @Override
    public void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
        throws IOException {
      readGroup(fieldNumber, builder, ExtensionRegistryLite.getEmptyRegistry());
    }

    @Override
    public void readMessage(
        final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
        throws IOException {
      final int length = readRawVarint32();
      if (recursionDepth >= recursionLimit) {
        throw InvalidProtocolBufferException.recursionLimitExceeded();
      }
      final int oldLimit = pushLimit(length);
      ++recursionDepth;
      builder.mergeFrom(this, extensionRegistry);
      checkLastTagWas(0);
      --recursionDepth;
      popLimit(oldLimit);
    }


    @Override
    public <T extends MessageLite> T readMessage(
        final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException {
      int length = readRawVarint32();
      if (recursionDepth >= recursionLimit) {
        throw InvalidProtocolBufferException.recursionLimitExceeded();
      }
      final int oldLimit = pushLimit(length);
      ++recursionDepth;
      T result = parser.parsePartialFrom(this, extensionRegistry);
      checkLastTagWas(0);
      --recursionDepth;
      popLimit(oldLimit);
      return result;
    }

    @Override
    public ByteString readBytes() throws IOException {
      final int size = readRawVarint32();
      if (size > 0 && size <= (limit - pos)) {
        // Fast path:  We already have the bytes in a contiguous buffer, so
        //   just copy directly from it.
        final ByteString result =
            immutable && enableAliasing
                ? ByteString.wrap(buffer, pos, size)
                : ByteString.copyFrom(buffer, pos, size);
        pos += size;
        return result;
      }
      if (size == 0) {
        return ByteString.EMPTY;
      }
      // Slow path:  Build a byte array first then copy it.
      return ByteString.wrap(readRawBytes(size));
    }

    @Override
    public byte[] readByteArray() throws IOException {
      final int size = readRawVarint32();
      return readRawBytes(size);
    }

    @Override
    public ByteBuffer readByteBuffer() throws IOException {
      final int size = readRawVarint32();
      if (size > 0 && size <= (limit - pos)) {
        // Fast path: We already have the bytes in a contiguous buffer.
        // When aliasing is enabled, we can return a ByteBuffer pointing directly
        // into the underlying byte array without copy if the CodedInputStream is
        // constructed from a byte array. If aliasing is disabled or the input is
        // from an InputStream or ByteString, we have to make a copy of the bytes.
        ByteBuffer result =
            !immutable && enableAliasing
                ? ByteBuffer.wrap(buffer, pos, size).slice()
                : ByteBuffer.wrap(Arrays.copyOfRange(buffer, pos, pos + size));
        pos += size;
        // TODO(nathanmittler): Investigate making the ByteBuffer be made read-only
        return result;
      }

      if (size == 0) {
        return EMPTY_BYTE_BUFFER;
      }
      if (size < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      throw InvalidProtocolBufferException.truncatedMessage();
    }

    @Override
    public int readUInt32() throws IOException {
      return readRawVarint32();
    }

    @Override
    public int readEnum() throws IOException {
      return readRawVarint32();
    }

    @Override
    public int readSFixed32() throws IOException {
      return readRawLittleEndian32();
    }

    @Override
    public long readSFixed64() throws IOException {
      return readRawLittleEndian64();
    }

    @Override
    public int readSInt32() throws IOException {
      return decodeZigZag32(readRawVarint32());
    }

    @Override
    public long readSInt64() throws IOException {
      return decodeZigZag64(readRawVarint64());
    }

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

    @Override
    public int readRawVarint32() throws IOException {
      // See implementation notes for readRawVarint64
      fastpath:
      {
        int tempPos = pos;

        if (limit == tempPos) {
          break fastpath;
        }

        final byte[] buffer = this.buffer;
        int x;
        if ((x = buffer[tempPos++]) >= 0) {
          pos = tempPos;
          return x;
        } else if (limit - tempPos < 9) {
          break fastpath;
        } else if ((x ^= (buffer[tempPos++] << 7)) < 0) {
          x ^= (~0 << 7);
        } else if ((x ^= (buffer[tempPos++] << 14)) >= 0) {
          x ^= (~0 << 7) ^ (~0 << 14);
        } else if ((x ^= (buffer[tempPos++] << 21)) < 0) {
          x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
        } else {
          int y = buffer[tempPos++];
          x ^= y << 28;
          x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
          if (y < 0
              && buffer[tempPos++] < 0
              && buffer[tempPos++] < 0
              && buffer[tempPos++] < 0
              && buffer[tempPos++] < 0
              && buffer[tempPos++] < 0) {
            break fastpath; // Will throw malformedVarint()
          }
        }
        pos = tempPos;
        return x;
      }
      return (int) readRawVarint64SlowPath();
    }

    private void skipRawVarint() throws IOException {
      if (limit - pos >= MAX_VARINT_SIZE) {
        skipRawVarintFastPath();
      } else {
        skipRawVarintSlowPath();
      }
    }

    private void skipRawVarintFastPath() throws IOException {
      for (int i = 0; i < MAX_VARINT_SIZE; i++) {
        if (buffer[pos++] >= 0) {
          return;
        }
      }
      throw InvalidProtocolBufferException.malformedVarint();
    }

    private void skipRawVarintSlowPath() throws IOException {
      for (int i = 0; i < MAX_VARINT_SIZE; i++) {
        if (readRawByte() >= 0) {
          return;
        }
      }
      throw InvalidProtocolBufferException.malformedVarint();
    }

    @Override
    public long readRawVarint64() throws IOException {
      // Implementation notes:
      //
      // Optimized for one-byte values, expected to be common.
      // The particular code below was selected from various candidates
      // empirically, by winning VarintBenchmark.
      //
      // Sign extension of (signed) Java bytes is usually a nuisance, but
      // we exploit it here to more easily obtain the sign of bytes read.
      // Instead of cleaning up the sign extension bits by masking eagerly,
      // we delay until we find the final (positive) byte, when we clear all
      // accumulated bits with one xor.  We depend on javac to constant fold.
      fastpath:
      {
        int tempPos = pos;

        if (limit == tempPos) {
          break fastpath;
        }

        final byte[] buffer = this.buffer;
        long x;
        int y;
        if ((y = buffer[tempPos++]) >= 0) {
          pos = tempPos;
          return y;
        } else if (limit - tempPos < 9) {
          break fastpath;
        } else if ((y ^= (buffer[tempPos++] << 7)) < 0) {
          x = y ^ (~0 << 7);
        } else if ((y ^= (buffer[tempPos++] << 14)) >= 0) {
          x = y ^ ((~0 << 7) ^ (~0 << 14));
        } else if ((y ^= (buffer[tempPos++] << 21)) < 0) {
          x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
        } else if ((x = y ^ ((long) buffer[tempPos++] << 28)) >= 0L) {
          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
        } else if ((x ^= ((long) buffer[tempPos++] << 35)) < 0L) {
          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
        } else if ((x ^= ((long) buffer[tempPos++] << 42)) >= 0L) {
          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
        } else if ((x ^= ((long) buffer[tempPos++] << 49)) < 0L) {
          x ^=
              (~0L << 7)
                  ^ (~0L << 14)
                  ^ (~0L << 21)
                  ^ (~0L << 28)
                  ^ (~0L << 35)
                  ^ (~0L << 42)
                  ^ (~0L << 49);
        } else {
          x ^= ((long) buffer[tempPos++] << 56);
          x ^=
              (~0L << 7)
                  ^ (~0L << 14)
                  ^ (~0L << 21)
                  ^ (~0L << 28)
                  ^ (~0L << 35)
                  ^ (~0L << 42)
                  ^ (~0L << 49)
                  ^ (~0L << 56);
          if (x < 0L) {
            if (buffer[tempPos++] < 0L) {
              break fastpath; // Will throw malformedVarint()
            }
          }
        }
        pos = tempPos;
        return x;
      }
      return readRawVarint64SlowPath();
    }

    @Override
    long readRawVarint64SlowPath() throws IOException {
      long result = 0;
      for (int shift = 0; shift < 64; shift += 7) {
        final byte b = readRawByte();
        result |= (long) (b & 0x7F) << shift;
        if ((b & 0x80) == 0) {
          return result;
        }
      }
      throw InvalidProtocolBufferException.malformedVarint();
    }

    @Override
    public int readRawLittleEndian32() throws IOException {
      int tempPos = pos;

      if (limit - tempPos < FIXED32_SIZE) {
        throw InvalidProtocolBufferException.truncatedMessage();
      }

      final byte[] buffer = this.buffer;
      pos = tempPos + FIXED32_SIZE;
      return (((buffer[tempPos] & 0xff))
          | ((buffer[tempPos + 1] & 0xff) << 8)
          | ((buffer[tempPos + 2] & 0xff) << 16)
          | ((buffer[tempPos + 3] & 0xff) << 24));
    }

    @Override
    public long readRawLittleEndian64() throws IOException {
      int tempPos = pos;

      if (limit - tempPos < FIXED64_SIZE) {
        throw InvalidProtocolBufferException.truncatedMessage();
      }

      final byte[] buffer = this.buffer;
      pos = tempPos + FIXED64_SIZE;
      return (((buffer[tempPos] & 0xffL))
          | ((buffer[tempPos + 1] & 0xffL) << 8)
          | ((buffer[tempPos + 2] & 0xffL) << 16)
          | ((buffer[tempPos + 3] & 0xffL) << 24)
          | ((buffer[tempPos + 4] & 0xffL) << 32)
          | ((buffer[tempPos + 5] & 0xffL) << 40)
          | ((buffer[tempPos + 6] & 0xffL) << 48)
          | ((buffer[tempPos + 7] & 0xffL) << 56));
    }

    @Override
    public void enableAliasing(boolean enabled) {
      this.enableAliasing = enabled;
    }

    @Override
    public void resetSizeCounter() {
      startPos = pos;
    }

    @Override
    public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
      if (byteLimit < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      byteLimit += getTotalBytesRead();
      final int oldLimit = currentLimit;
      if (byteLimit > oldLimit) {
        throw InvalidProtocolBufferException.truncatedMessage();
      }
      currentLimit = byteLimit;

      recomputeBufferSizeAfterLimit();

      return oldLimit;
    }

    private void recomputeBufferSizeAfterLimit() {
      limit += bufferSizeAfterLimit;
      final int bufferEnd = limit - startPos;
      if (bufferEnd > currentLimit) {
        // Limit is in current buffer.
        bufferSizeAfterLimit = bufferEnd - currentLimit;
        limit -= bufferSizeAfterLimit;
      } else {
        bufferSizeAfterLimit = 0;
      }
    }

    @Override
    public void popLimit(final int oldLimit) {
      currentLimit = oldLimit;
      recomputeBufferSizeAfterLimit();
    }

    @Override
    public int getBytesUntilLimit() {
      if (currentLimit == Integer.MAX_VALUE) {
        return -1;
      }

      return currentLimit - getTotalBytesRead();
    }

    @Override
    public boolean isAtEnd() throws IOException {
      return pos == limit;
    }

    @Override
    public int getTotalBytesRead() {
      return pos - startPos;
    }

    @Override
    public byte readRawByte() throws IOException {
      if (pos == limit) {
        throw InvalidProtocolBufferException.truncatedMessage();
      }
      return buffer[pos++];
    }

    @Override
    public byte[] readRawBytes(final int length) throws IOException {
      if (length > 0 && length <= (limit - pos)) {
        final int tempPos = pos;
        pos += length;
        return Arrays.copyOfRange(buffer, tempPos, pos);
      }

      if (length <= 0) {
        if (length == 0) {
          return Internal.EMPTY_BYTE_ARRAY;
        } else {
          throw InvalidProtocolBufferException.negativeSize();
        }
      }
      throw InvalidProtocolBufferException.truncatedMessage();
    }

    @Override
    public void skipRawBytes(final int length) throws IOException {
      if (length >= 0 && length <= (limit - pos)) {
        // We have all the bytes we need already.
        pos += length;
        return;
      }

      if (length < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      throw InvalidProtocolBufferException.truncatedMessage();
    }
  }

  /**
   * A {@link CodedInputStream} implementation that uses a backing direct ByteBuffer as the input.
   * Requires the use of {@code sun.misc.Unsafe} to perform fast reads on the buffer.
   */
  private static final class UnsafeDirectNioDecoder extends CodedInputStream {
    /** The direct buffer that is backing this stream. */
    private final ByteBuffer buffer;

    /**
     * If {@code true}, indicates that the buffer is backing a {@link ByteString} and is therefore
     * considered to be an immutable input source.
     */
    private final boolean immutable;

    /** The unsafe address of the content of {@link #buffer}. */
    private final long address;

    /** The unsafe address of the current read limit of the buffer. */
    private long limit;

    /** The unsafe address of the current read position of the buffer. */
    private long pos;

    /** The unsafe address of the starting read position. */
    private long startPos;

    /** The amount of available data in the buffer beyond {@link #limit}. */
    private int bufferSizeAfterLimit;

    /** The last tag that was read from this stream. */
    private int lastTag;

    /**
     * If {@code true}, indicates that calls to read {@link ByteString} or {@code byte[]}
     * <strong>may</strong> return slices of the underlying buffer, rather than copies.
     */
    private boolean enableAliasing;

    /** The absolute position of the end of the current message. */
    private int currentLimit = Integer.MAX_VALUE;

    static boolean isSupported() {
      return UnsafeUtil.hasUnsafeByteBufferOperations();
    }

    private UnsafeDirectNioDecoder(ByteBuffer buffer, boolean immutable) {
      this.buffer = buffer;
      address = UnsafeUtil.addressOffset(buffer);
      limit = address + buffer.limit();
      pos = address + buffer.position();
      startPos = pos;
      this.immutable = immutable;
    }

    @Override
    public int readTag() throws IOException {
      if (isAtEnd()) {
        lastTag = 0;
        return 0;
      }

      lastTag = readRawVarint32();
      if (WireFormat.getTagFieldNumber(lastTag) == 0) {
        // If we actually read zero (or any tag number corresponding to field
        // number zero), that's not a valid tag.
        throw InvalidProtocolBufferException.invalidTag();
      }
      return lastTag;
    }

    @Override
    public void checkLastTagWas(final int value) throws InvalidProtocolBufferException {
      if (lastTag != value) {
        throw InvalidProtocolBufferException.invalidEndTag();
      }
    }

    @Override
    public int getLastTag() {
      return lastTag;
    }

    @Override
    public boolean skipField(final int tag) throws IOException {
      switch (WireFormat.getTagWireType(tag)) {
        case WireFormat.WIRETYPE_VARINT:
          skipRawVarint();
          return true;
        case WireFormat.WIRETYPE_FIXED64:
          skipRawBytes(FIXED64_SIZE);
          return true;
        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
          skipRawBytes(readRawVarint32());
          return true;
        case WireFormat.WIRETYPE_START_GROUP:
          skipMessage();
          checkLastTagWas(
              WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
          return true;
        case WireFormat.WIRETYPE_END_GROUP:
          return false;
        case WireFormat.WIRETYPE_FIXED32:
          skipRawBytes(FIXED32_SIZE);
          return true;
        default:
          throw InvalidProtocolBufferException.invalidWireType();
      }
    }

    @Override
    public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
      switch (WireFormat.getTagWireType(tag)) {
        case WireFormat.WIRETYPE_VARINT:
          {
            long value = readInt64();
            output.writeRawVarint32(tag);
            output.writeUInt64NoTag(value);
            return true;
          }
        case WireFormat.WIRETYPE_FIXED64:
          {
            long value = readRawLittleEndian64();
            output.writeRawVarint32(tag);
            output.writeFixed64NoTag(value);
            return true;
          }
        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
          {
            ByteString value = readBytes();
            output.writeRawVarint32(tag);
            output.writeBytesNoTag(value);
            return true;
          }
        case WireFormat.WIRETYPE_START_GROUP:
          {
            output.writeRawVarint32(tag);
            skipMessage(output);
            int endtag =
                WireFormat.makeTag(
                    WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
            checkLastTagWas(endtag);
            output.writeRawVarint32(endtag);
            return true;
          }
        case WireFormat.WIRETYPE_END_GROUP:
          {
            return false;
          }
        case WireFormat.WIRETYPE_FIXED32:
          {
            int value = readRawLittleEndian32();
            output.writeRawVarint32(tag);
            output.writeFixed32NoTag(value);
            return true;
          }
        default:
          throw InvalidProtocolBufferException.invalidWireType();
      }
    }

    @Override
    public void skipMessage() throws IOException {
      while (true) {
        final int tag = readTag();
        if (tag == 0 || !skipField(tag)) {
          return;
        }
      }
    }

    @Override
    public void skipMessage(CodedOutputStream output) throws IOException {
      while (true) {
        final int tag = readTag();
        if (tag == 0 || !skipField(tag, output)) {
          return;
        }
      }
    }


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

    @Override
    public double readDouble() throws IOException {
      return Double.longBitsToDouble(readRawLittleEndian64());
    }

    @Override
    public float readFloat() throws IOException {
      return Float.intBitsToFloat(readRawLittleEndian32());
    }

    @Override
    public long readUInt64() throws IOException {
      return readRawVarint64();
    }

    @Override
    public long readInt64() throws IOException {
      return readRawVarint64();
    }

    @Override
    public int readInt32() throws IOException {
      return readRawVarint32();
    }

    @Override
    public long readFixed64() throws IOException {
      return readRawLittleEndian64();
    }

    @Override
    public int readFixed32() throws IOException {
      return readRawLittleEndian32();
    }

    @Override
    public boolean readBool() throws IOException {
      return readRawVarint64() != 0;
    }

    @Override
    public String readString() throws IOException {
      final int size = readRawVarint32();
      if (size > 0 && size <= remaining()) {
        // TODO(nathanmittler): Is there a way to avoid this copy?
        // TODO(anuraaga): It might be possible to share the optimized loop with
        // readStringRequireUtf8 by implementing Java replacement logic there.
        // The same as readBytes' logic
        byte[] bytes = new byte[size];
        UnsafeUtil.copyMemory(pos, bytes, 0, size);
        String result = new String(bytes, UTF_8);
        pos += size;
        return result;
      }

      if (size == 0) {
        return "";
      }
      if (size < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      throw InvalidProtocolBufferException.truncatedMessage();
    }

    @Override
    public String readStringRequireUtf8() throws IOException {
      final int size = readRawVarint32();
      if (size > 0 && size <= remaining()) {
        final int bufferPos = bufferPos(pos);
        String result = Utf8.decodeUtf8(buffer, bufferPos, size);
        pos += size;
        return result;
      }

      if (size == 0) {
        return "";
      }
      if (size <= 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      throw InvalidProtocolBufferException.truncatedMessage();
    }

    @Override
    public void readGroup(
        final int fieldNumber,
        final MessageLite.Builder builder,
        final ExtensionRegistryLite extensionRegistry)
        throws IOException {
      if (recursionDepth >= recursionLimit) {
        throw InvalidProtocolBufferException.recursionLimitExceeded();
      }
      ++recursionDepth;
      builder.mergeFrom(this, extensionRegistry);
      checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
      --recursionDepth;
    }


    @Override
    public <T extends MessageLite> T readGroup(
        final int fieldNumber,
        final Parser<T> parser,
        final ExtensionRegistryLite extensionRegistry)
        throws IOException {
      if (recursionDepth >= recursionLimit) {
        throw InvalidProtocolBufferException.recursionLimitExceeded();
      }
      ++recursionDepth;
      T result = parser.parsePartialFrom(this, extensionRegistry);
      checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
      --recursionDepth;
      return result;
    }

    @Deprecated
    @Override
    public void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
        throws IOException {
      readGroup(fieldNumber, builder, ExtensionRegistryLite.getEmptyRegistry());
    }

    @Override
    public void readMessage(
        final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
        throws IOException {
      final int length = readRawVarint32();
      if (recursionDepth >= recursionLimit) {
        throw InvalidProtocolBufferException.recursionLimitExceeded();
      }
      final int oldLimit = pushLimit(length);
      ++recursionDepth;
      builder.mergeFrom(this, extensionRegistry);
      checkLastTagWas(0);
      --recursionDepth;
      popLimit(oldLimit);
    }


    @Override
    public <T extends MessageLite> T readMessage(
        final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException {
      int length = readRawVarint32();
      if (recursionDepth >= recursionLimit) {
        throw InvalidProtocolBufferException.recursionLimitExceeded();
      }
      final int oldLimit = pushLimit(length);
      ++recursionDepth;
      T result = parser.parsePartialFrom(this, extensionRegistry);
      checkLastTagWas(0);
      --recursionDepth;
      popLimit(oldLimit);
      return result;
    }

    @Override
    public ByteString readBytes() throws IOException {
      final int size = readRawVarint32();
      if (size > 0 && size <= remaining()) {
        if (immutable && enableAliasing) {
          final ByteBuffer result = slice(pos, pos + size);
          pos += size;
          return ByteString.wrap(result);
        } else {
          // Use UnsafeUtil to copy the memory to bytes instead of using ByteBuffer ways.
          byte[] bytes = new byte[size];
          UnsafeUtil.copyMemory(pos, bytes, 0, size);
          pos += size;
          return ByteString.wrap(bytes);
        }
      }

      if (size == 0) {
        return ByteString.EMPTY;
      }
      if (size < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      throw InvalidProtocolBufferException.truncatedMessage();
    }

    @Override
    public byte[] readByteArray() throws IOException {
      return readRawBytes(readRawVarint32());
    }

    @Override
    public ByteBuffer readByteBuffer() throws IOException {
      final int size = readRawVarint32();
      if (size > 0 && size <= remaining()) {
        // "Immutable" implies that buffer is backing a ByteString.
        // Disallow slicing in this case to prevent the caller from modifying the contents
        // of the ByteString.
        if (!immutable && enableAliasing) {
          final ByteBuffer result = slice(pos, pos + size);
          pos += size;
          return result;
        } else {
          // The same as readBytes' logic
          byte[] bytes = new byte[size];
          UnsafeUtil.copyMemory(pos, bytes, 0, size);
          pos += size;
          return ByteBuffer.wrap(bytes);
        }
        // TODO(nathanmittler): Investigate making the ByteBuffer be made read-only
      }

      if (size == 0) {
        return EMPTY_BYTE_BUFFER;
      }
      if (size < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      throw InvalidProtocolBufferException.truncatedMessage();
    }

    @Override
    public int readUInt32() throws IOException {
      return readRawVarint32();
    }

    @Override
    public int readEnum() throws IOException {
      return readRawVarint32();
    }

    @Override
    public int readSFixed32() throws IOException {
      return readRawLittleEndian32();
    }

    @Override
    public long readSFixed64() throws IOException {
      return readRawLittleEndian64();
    }

    @Override
    public int readSInt32() throws IOException {
      return decodeZigZag32(readRawVarint32());
    }

    @Override
    public long readSInt64() throws IOException {
      return decodeZigZag64(readRawVarint64());
    }

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

    @Override
    public int readRawVarint32() throws IOException {
      // See implementation notes for readRawVarint64
      fastpath:
      {
        long tempPos = pos;

        if (limit == tempPos) {
          break fastpath;
        }

        int x;
        if ((x = UnsafeUtil.getByte(tempPos++)) >= 0) {
          pos = tempPos;
          return x;
        } else if (limit - tempPos < 9) {
          break fastpath;
        } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 7)) < 0) {
          x ^= (~0 << 7);
        } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 14)) >= 0) {
          x ^= (~0 << 7) ^ (~0 << 14);
        } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 21)) < 0) {
          x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
        } else {
          int y = UnsafeUtil.getByte(tempPos++);
          x ^= y << 28;
          x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
          if (y < 0
              && UnsafeUtil.getByte(tempPos++) < 0
              && UnsafeUtil.getByte(tempPos++) < 0
              && UnsafeUtil.getByte(tempPos++) < 0
              && UnsafeUtil.getByte(tempPos++) < 0
              && UnsafeUtil.getByte(tempPos++) < 0) {
            break fastpath; // Will throw malformedVarint()
          }
        }
        pos = tempPos;
        return x;
      }
      return (int) readRawVarint64SlowPath();
    }

    private void skipRawVarint() throws IOException {
      if (remaining() >= MAX_VARINT_SIZE) {
        skipRawVarintFastPath();
      } else {
        skipRawVarintSlowPath();
      }
    }

    private void skipRawVarintFastPath() throws IOException {
      for (int i = 0; i < MAX_VARINT_SIZE; i++) {
        if (UnsafeUtil.getByte(pos++) >= 0) {
          return;
        }
      }
      throw InvalidProtocolBufferException.malformedVarint();
    }

    private void skipRawVarintSlowPath() throws IOException {
      for (int i = 0; i < MAX_VARINT_SIZE; i++) {
        if (readRawByte() >= 0) {
          return;
        }
      }
      throw InvalidProtocolBufferException.malformedVarint();
    }

    @Override
    public long readRawVarint64() throws IOException {
      // Implementation notes:
      //
      // Optimized for one-byte values, expected to be common.
      // The particular code below was selected from various candidates
      // empirically, by winning VarintBenchmark.
      //
      // Sign extension of (signed) Java bytes is usually a nuisance, but
      // we exploit it here to more easily obtain the sign of bytes read.
      // Instead of cleaning up the sign extension bits by masking eagerly,
      // we delay until we find the final (positive) byte, when we clear all
      // accumulated bits with one xor.  We depend on javac to constant fold.
      fastpath:
      {
        long tempPos = pos;

        if (limit == tempPos) {
          break fastpath;
        }

        long x;
        int y;
        if ((y = UnsafeUtil.getByte(tempPos++)) >= 0) {
          pos = tempPos;
          return y;
        } else if (limit - tempPos < 9) {
          break fastpath;
        } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 7)) < 0) {
          x = y ^ (~0 << 7);
        } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 14)) >= 0) {
          x = y ^ ((~0 << 7) ^ (~0 << 14));
        } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 21)) < 0) {
          x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
        } else if ((x = y ^ ((long) UnsafeUtil.getByte(tempPos++) << 28)) >= 0L) {
          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
        } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 35)) < 0L) {
          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
        } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 42)) >= 0L) {
          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
        } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 49)) < 0L) {
          x ^=
              (~0L << 7)
                  ^ (~0L << 14)
                  ^ (~0L << 21)
                  ^ (~0L << 28)
                  ^ (~0L << 35)
                  ^ (~0L << 42)
                  ^ (~0L << 49);
        } else {
          x ^= ((long) UnsafeUtil.getByte(tempPos++) << 56);
          x ^=
              (~0L << 7)
                  ^ (~0L << 14)
                  ^ (~0L << 21)
                  ^ (~0L << 28)
                  ^ (~0L << 35)
                  ^ (~0L << 42)
                  ^ (~0L << 49)
                  ^ (~0L << 56);
          if (x < 0L) {
            if (UnsafeUtil.getByte(tempPos++) < 0L) {
              break fastpath; // Will throw malformedVarint()
            }
          }
        }
        pos = tempPos;
        return x;
      }
      return readRawVarint64SlowPath();
    }

    @Override
    long readRawVarint64SlowPath() throws IOException {
      long result = 0;
      for (int shift = 0; shift < 64; shift += 7) {
        final byte b = readRawByte();
        result |= (long) (b & 0x7F) << shift;
        if ((b & 0x80) == 0) {
          return result;
        }
      }
      throw InvalidProtocolBufferException.malformedVarint();
    }

    @Override
    public int readRawLittleEndian32() throws IOException {
      long tempPos = pos;

      if (limit - tempPos < FIXED32_SIZE) {
        throw InvalidProtocolBufferException.truncatedMessage();
      }

      pos = tempPos + FIXED32_SIZE;
      return (((UnsafeUtil.getByte(tempPos) & 0xff))
          | ((UnsafeUtil.getByte(tempPos + 1) & 0xff) << 8)
          | ((UnsafeUtil.getByte(tempPos + 2) & 0xff) << 16)
          | ((UnsafeUtil.getByte(tempPos + 3) & 0xff) << 24));
    }

    @Override
    public long readRawLittleEndian64() throws IOException {
      long tempPos = pos;

      if (limit - tempPos < FIXED64_SIZE) {
        throw InvalidProtocolBufferException.truncatedMessage();
      }

      pos = tempPos + FIXED64_SIZE;
      return (((UnsafeUtil.getByte(tempPos) & 0xffL))
          | ((UnsafeUtil.getByte(tempPos + 1) & 0xffL) << 8)
          | ((UnsafeUtil.getByte(tempPos + 2) & 0xffL) << 16)
          | ((UnsafeUtil.getByte(tempPos + 3) & 0xffL) << 24)
          | ((UnsafeUtil.getByte(tempPos + 4) & 0xffL) << 32)
          | ((UnsafeUtil.getByte(tempPos + 5) & 0xffL) << 40)
          | ((UnsafeUtil.getByte(tempPos + 6) & 0xffL) << 48)
          | ((UnsafeUtil.getByte(tempPos + 7) & 0xffL) << 56));
    }

    @Override
    public void enableAliasing(boolean enabled) {
      this.enableAliasing = enabled;
    }

    @Override
    public void resetSizeCounter() {
      startPos = pos;
    }

    @Override
    public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
      if (byteLimit < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      byteLimit += getTotalBytesRead();
      final int oldLimit = currentLimit;
      if (byteLimit > oldLimit) {
        throw InvalidProtocolBufferException.truncatedMessage();
      }
      currentLimit = byteLimit;

      recomputeBufferSizeAfterLimit();

      return oldLimit;
    }

    @Override
    public void popLimit(final int oldLimit) {
      currentLimit = oldLimit;
      recomputeBufferSizeAfterLimit();
    }

    @Override
    public int getBytesUntilLimit() {
      if (currentLimit == Integer.MAX_VALUE) {
        return -1;
      }

      return currentLimit - getTotalBytesRead();
    }

    @Override
    public boolean isAtEnd() throws IOException {
      return pos == limit;
    }

    @Override
    public int getTotalBytesRead() {
      return (int) (pos - startPos);
    }

    @Override
    public byte readRawByte() throws IOException {
      if (pos == limit) {
        throw InvalidProtocolBufferException.truncatedMessage();
      }
      return UnsafeUtil.getByte(pos++);
    }

    @Override
    public byte[] readRawBytes(final int length) throws IOException {
      if (length >= 0 && length <= remaining()) {
        byte[] bytes = new byte[length];
        slice(pos, pos + length).get(bytes);
        pos += length;
        return bytes;
      }

      if (length <= 0) {
        if (length == 0) {
          return EMPTY_BYTE_ARRAY;
        } else {
          throw InvalidProtocolBufferException.negativeSize();
        }
      }

      throw InvalidProtocolBufferException.truncatedMessage();
    }

    @Override
    public void skipRawBytes(final int length) throws IOException {
      if (length >= 0 && length <= remaining()) {
        // We have all the bytes we need already.
        pos += length;
        return;
      }

      if (length < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      throw InvalidProtocolBufferException.truncatedMessage();
    }

    private void recomputeBufferSizeAfterLimit() {
      limit += bufferSizeAfterLimit;
      final int bufferEnd = (int) (limit - startPos);
      if (bufferEnd > currentLimit) {
        // Limit is in current buffer.
        bufferSizeAfterLimit = bufferEnd - currentLimit;
        limit -= bufferSizeAfterLimit;
      } else {
        bufferSizeAfterLimit = 0;
      }
    }

    private int remaining() {
      return (int) (limit - pos);
    }

    private int bufferPos(long pos) {
      return (int) (pos - address);
    }

    private ByteBuffer slice(long begin, long end) throws IOException {
      int prevPos = buffer.position();
      int prevLimit = buffer.limit();
      try {
        buffer.position(bufferPos(begin));
        buffer.limit(bufferPos(end));
        return buffer.slice();
      } catch (IllegalArgumentException e) {
        throw InvalidProtocolBufferException.truncatedMessage();
      } finally {
        buffer.position(prevPos);
        buffer.limit(prevLimit);
      }
    }
  }

  /**
   * Implementation of {@link CodedInputStream} that uses an {@link InputStream} as the data source.
   */
  private static final class StreamDecoder extends CodedInputStream {
    private final InputStream input;
    private final byte[] buffer;
    /** bufferSize represents how many bytes are currently filled in the buffer */
    private int bufferSize;

    private int bufferSizeAfterLimit;
    private int pos;
    private int lastTag;

    /**
     * The total number of bytes read before the current buffer. The total bytes read up to the
     * current position can be computed as {@code totalBytesRetired + pos}. This value may be
     * negative if reading started in the middle of the current buffer (e.g. if the constructor that
     * takes a byte array and an offset was used).
     */
    private int totalBytesRetired;

    /** The absolute position of the end of the current message. */
    private int currentLimit = Integer.MAX_VALUE;

    private StreamDecoder(final InputStream input, int bufferSize) {
      checkNotNull(input, "input");
      this.input = input;
      this.buffer = new byte[bufferSize];
      this.bufferSize = 0;
      pos = 0;
      totalBytesRetired = 0;
    }

    @Override
    public int readTag() throws IOException {
      if (isAtEnd()) {
        lastTag = 0;
        return 0;
      }

      lastTag = readRawVarint32();
      if (WireFormat.getTagFieldNumber(lastTag) == 0) {
        // If we actually read zero (or any tag number corresponding to field
        // number zero), that's not a valid tag.
        throw InvalidProtocolBufferException.invalidTag();
      }
      return lastTag;
    }

    @Override
    public void checkLastTagWas(final int value) throws InvalidProtocolBufferException {
      if (lastTag != value) {
        throw InvalidProtocolBufferException.invalidEndTag();
      }
    }

    @Override
    public int getLastTag() {
      return lastTag;
    }

    @Override
    public boolean skipField(final int tag) throws IOException {
      switch (WireFormat.getTagWireType(tag)) {
        case WireFormat.WIRETYPE_VARINT:
          skipRawVarint();
          return true;
        case WireFormat.WIRETYPE_FIXED64:
          skipRawBytes(FIXED64_SIZE);
          return true;
        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
          skipRawBytes(readRawVarint32());
          return true;
        case WireFormat.WIRETYPE_START_GROUP:
          skipMessage();
          checkLastTagWas(
              WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
          return true;
        case WireFormat.WIRETYPE_END_GROUP:
          return false;
        case WireFormat.WIRETYPE_FIXED32:
          skipRawBytes(FIXED32_SIZE);
          return true;
        default:
          throw InvalidProtocolBufferException.invalidWireType();
      }
    }

    @Override
    public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
      switch (WireFormat.getTagWireType(tag)) {
        case WireFormat.WIRETYPE_VARINT:
          {
            long value = readInt64();
            output.writeRawVarint32(tag);
            output.writeUInt64NoTag(value);
            return true;
          }
        case WireFormat.WIRETYPE_FIXED64:
          {
            long value = readRawLittleEndian64();
            output.writeRawVarint32(tag);
            output.writeFixed64NoTag(value);
            return true;
          }
        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
          {
            ByteString value = readBytes();
            output.writeRawVarint32(tag);
            output.writeBytesNoTag(value);
            return true;
          }
        case WireFormat.WIRETYPE_START_GROUP:
          {
            output.writeRawVarint32(tag);
            skipMessage(output);
            int endtag =
                WireFormat.makeTag(
                    WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
            checkLastTagWas(endtag);
            output.writeRawVarint32(endtag);
            return true;
          }
        case WireFormat.WIRETYPE_END_GROUP:
          {
            return false;
          }
        case WireFormat.WIRETYPE_FIXED32:
          {
            int value = readRawLittleEndian32();
            output.writeRawVarint32(tag);
            output.writeFixed32NoTag(value);
            return true;
          }
        default:
          throw InvalidProtocolBufferException.invalidWireType();
      }
    }

    @Override
    public void skipMessage() throws IOException {
      while (true) {
        final int tag = readTag();
        if (tag == 0 || !skipField(tag)) {
          return;
        }
      }
    }

    @Override
    public void skipMessage(CodedOutputStream output) throws IOException {
      while (true) {
        final int tag = readTag();
        if (tag == 0 || !skipField(tag, output)) {
          return;
        }
      }
    }

    /** Collects the bytes skipped and returns the data in a ByteBuffer. */
    private class SkippedDataSink implements RefillCallback {
      private int lastPos = pos;
      private ByteArrayOutputStream byteArrayStream;

      @Override
      public void onRefill() {
        if (byteArrayStream == null) {
          byteArrayStream = new ByteArrayOutputStream();
        }
        byteArrayStream.write(buffer, lastPos, pos - lastPos);
        lastPos = 0;
      }

      /** Gets skipped data in a ByteBuffer. This method should only be called once. */
      ByteBuffer getSkippedData() {
        if (byteArrayStream == null) {
          return ByteBuffer.wrap(buffer, lastPos, pos - lastPos);
        } else {
          byteArrayStream.write(buffer, lastPos, pos);
          return ByteBuffer.wrap(byteArrayStream.toByteArray());
        }
      }
    }


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

    @Override
    public double readDouble() throws IOException {
      return Double.longBitsToDouble(readRawLittleEndian64());
    }

    @Override
    public float readFloat() throws IOException {
      return Float.intBitsToFloat(readRawLittleEndian32());
    }

    @Override
    public long readUInt64() throws IOException {
      return readRawVarint64();
    }

    @Override
    public long readInt64() throws IOException {
      return readRawVarint64();
    }

    @Override
    public int readInt32() throws IOException {
      return readRawVarint32();
    }

    @Override
    public long readFixed64() throws IOException {
      return readRawLittleEndian64();
    }

    @Override
    public int readFixed32() throws IOException {
      return readRawLittleEndian32();
    }

    @Override
    public boolean readBool() throws IOException {
      return readRawVarint64() != 0;
    }

    @Override
    public String readString() throws IOException {
      final int size = readRawVarint32();
      if (size > 0 && size <= (bufferSize - pos)) {
        // Fast path:  We already have the bytes in a contiguous buffer, so
        //   just copy directly from it.
        final String result = new String(buffer, pos, size, UTF_8);
        pos += size;
        return result;
      }
      if (size == 0) {
        return "";
      }
      if (size <= bufferSize) {
        refillBuffer(size);
        String result = new String(buffer, pos, size, UTF_8);
        pos += size;
        return result;
      }
      // Slow path:  Build a byte array first then copy it.
      return new String(readRawBytesSlowPath(size), UTF_8);
    }

    @Override
    public String readStringRequireUtf8() throws IOException {
      final int size = readRawVarint32();
      final byte[] bytes;
      final int oldPos = pos;
      final int tempPos;
      if (size <= (bufferSize - oldPos) && size > 0) {
        // Fast path:  We already have the bytes in a contiguous buffer, so
        //   just copy directly from it.
        bytes = buffer;
        pos = oldPos + size;
        tempPos = oldPos;
      } else if (size == 0) {
        return "";
      } else if (size <= bufferSize) {
        refillBuffer(size);
        bytes = buffer;
        tempPos = 0;
        pos = tempPos + size;
      } else {
        // Slow path:  Build a byte array first then copy it.
        bytes = readRawBytesSlowPath(size);
        tempPos = 0;
      }
      return Utf8.decodeUtf8(bytes, tempPos, size);
    }

    @Override
    public void readGroup(
        final int fieldNumber,
        final MessageLite.Builder builder,
        final ExtensionRegistryLite extensionRegistry)
        throws IOException {
      if (recursionDepth >= recursionLimit) {
        throw InvalidProtocolBufferException.recursionLimitExceeded();
      }
      ++recursionDepth;
      builder.mergeFrom(this, extensionRegistry);
      checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
      --recursionDepth;
    }


    @Override
    public <T extends MessageLite> T readGroup(
        final int fieldNumber,
        final Parser<T> parser,
        final ExtensionRegistryLite extensionRegistry)
        throws IOException {
      if (recursionDepth >= recursionLimit) {
        throw InvalidProtocolBufferException.recursionLimitExceeded();
      }
      ++recursionDepth;
      T result = parser.parsePartialFrom(this, extensionRegistry);
      checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
      --recursionDepth;
      return result;
    }

    @Deprecated
    @Override
    public void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
        throws IOException {
      readGroup(fieldNumber, builder, ExtensionRegistryLite.getEmptyRegistry());
    }

    @Override
    public void readMessage(
        final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
        throws IOException {
      final int length = readRawVarint32();
      if (recursionDepth >= recursionLimit) {
        throw InvalidProtocolBufferException.recursionLimitExceeded();
      }
      final int oldLimit = pushLimit(length);
      ++recursionDepth;
      builder.mergeFrom(this, extensionRegistry);
      checkLastTagWas(0);
      --recursionDepth;
      popLimit(oldLimit);
    }


    @Override
    public <T extends MessageLite> T readMessage(
        final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException {
      int length = readRawVarint32();
      if (recursionDepth >= recursionLimit) {
        throw InvalidProtocolBufferException.recursionLimitExceeded();
      }
      final int oldLimit = pushLimit(length);
      ++recursionDepth;
      T result = parser.parsePartialFrom(this, extensionRegistry);
      checkLastTagWas(0);
      --recursionDepth;
      popLimit(oldLimit);
      return result;
    }

    @Override
    public ByteString readBytes() throws IOException {
      final int size = readRawVarint32();
      if (size <= (bufferSize - pos) && size > 0) {
        // Fast path:  We already have the bytes in a contiguous buffer, so
        //   just copy directly from it.
        final ByteString result = ByteString.copyFrom(buffer, pos, size);
        pos += size;
        return result;
      }
      if (size == 0) {
        return ByteString.EMPTY;
      }
      return readBytesSlowPath(size);
    }

    @Override
    public byte[] readByteArray() throws IOException {
      final int size = readRawVarint32();
      if (size <= (bufferSize - pos) && size > 0) {
        // Fast path: We already have the bytes in a contiguous buffer, so
        // just copy directly from it.
        final byte[] result = Arrays.copyOfRange(buffer, pos, pos + size);
        pos += size;
        return result;
      } else {
        // Slow path: Build a byte array first then copy it.
        return readRawBytesSlowPath(size);
      }
    }

    @Override
    public ByteBuffer readByteBuffer() throws IOException {
      final int size = readRawVarint32();
      if (size <= (bufferSize - pos) && size > 0) {
        // Fast path: We already have the bytes in a contiguous buffer.
        ByteBuffer result = ByteBuffer.wrap(Arrays.copyOfRange(buffer, pos, pos + size));
        pos += size;
        return result;
      }
      if (size == 0) {
        return Internal.EMPTY_BYTE_BUFFER;
      }
      // Slow path: Build a byte array first then copy it.
      return ByteBuffer.wrap(readRawBytesSlowPath(size));
    }

    @Override
    public int readUInt32() throws IOException {
      return readRawVarint32();
    }

    @Override
    public int readEnum() throws IOException {
      return readRawVarint32();
    }

    @Override
    public int readSFixed32() throws IOException {
      return readRawLittleEndian32();
    }

    @Override
    public long readSFixed64() throws IOException {
      return readRawLittleEndian64();
    }

    @Override
    public int readSInt32() throws IOException {
      return decodeZigZag32(readRawVarint32());
    }

    @Override
    public long readSInt64() throws IOException {
      return decodeZigZag64(readRawVarint64());
    }

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

    @Override
    public int readRawVarint32() throws IOException {
      // See implementation notes for readRawVarint64
      fastpath:
      {
        int tempPos = pos;

        if (bufferSize == tempPos) {
          break fastpath;
        }

        final byte[] buffer = this.buffer;
        int x;
        if ((x = buffer[tempPos++]) >= 0) {
          pos = tempPos;
          return x;
        } else if (bufferSize - tempPos < 9) {
          break fastpath;
        } else if ((x ^= (buffer[tempPos++] << 7)) < 0) {
          x ^= (~0 << 7);
        } else if ((x ^= (buffer[tempPos++] << 14)) >= 0) {
          x ^= (~0 << 7) ^ (~0 << 14);
        } else if ((x ^= (buffer[tempPos++] << 21)) < 0) {
          x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
        } else {
          int y = buffer[tempPos++];
          x ^= y << 28;
          x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
          if (y < 0
              && buffer[tempPos++] < 0
              && buffer[tempPos++] < 0
              && buffer[tempPos++] < 0
              && buffer[tempPos++] < 0
              && buffer[tempPos++] < 0) {
            break fastpath; // Will throw malformedVarint()
          }
        }
        pos = tempPos;
        return x;
      }
      return (int) readRawVarint64SlowPath();
    }

    private void skipRawVarint() throws IOException {
      if (bufferSize - pos >= MAX_VARINT_SIZE) {
        skipRawVarintFastPath();
      } else {
        skipRawVarintSlowPath();
      }
    }

    private void skipRawVarintFastPath() throws IOException {
      for (int i = 0; i < MAX_VARINT_SIZE; i++) {
        if (buffer[pos++] >= 0) {
          return;
        }
      }
      throw InvalidProtocolBufferException.malformedVarint();
    }

    private void skipRawVarintSlowPath() throws IOException {
      for (int i = 0; i < MAX_VARINT_SIZE; i++) {
        if (readRawByte() >= 0) {
          return;
        }
      }
      throw InvalidProtocolBufferException.malformedVarint();
    }

    @Override
    public long readRawVarint64() throws IOException {
      // Implementation notes:
      //
      // Optimized for one-byte values, expected to be common.
      // The particular code below was selected from various candidates
      // empirically, by winning VarintBenchmark.
      //
      // Sign extension of (signed) Java bytes is usually a nuisance, but
      // we exploit it here to more easily obtain the sign of bytes read.
      // Instead of cleaning up the sign extension bits by masking eagerly,
      // we delay until we find the final (positive) byte, when we clear all
      // accumulated bits with one xor.  We depend on javac to constant fold.
      fastpath:
      {
        int tempPos = pos;

        if (bufferSize == tempPos) {
          break fastpath;
        }

        final byte[] buffer = this.buffer;
        long x;
        int y;
        if ((y = buffer[tempPos++]) >= 0) {
          pos = tempPos;
          return y;
        } else if (bufferSize - tempPos < 9) {
          break fastpath;
        } else if ((y ^= (buffer[tempPos++] << 7)) < 0) {
          x = y ^ (~0 << 7);
        } else if ((y ^= (buffer[tempPos++] << 14)) >= 0) {
          x = y ^ ((~0 << 7) ^ (~0 << 14));
        } else if ((y ^= (buffer[tempPos++] << 21)) < 0) {
          x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
        } else if ((x = y ^ ((long) buffer[tempPos++] << 28)) >= 0L) {
          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
        } else if ((x ^= ((long) buffer[tempPos++] << 35)) < 0L) {
          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
        } else if ((x ^= ((long) buffer[tempPos++] << 42)) >= 0L) {
          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
        } else if ((x ^= ((long) buffer[tempPos++] << 49)) < 0L) {
          x ^=
              (~0L << 7)
                  ^ (~0L << 14)
                  ^ (~0L << 21)
                  ^ (~0L << 28)
                  ^ (~0L << 35)
                  ^ (~0L << 42)
                  ^ (~0L << 49);
        } else {
          x ^= ((long) buffer[tempPos++] << 56);
          x ^=
              (~0L << 7)
                  ^ (~0L << 14)
                  ^ (~0L << 21)
                  ^ (~0L << 28)
                  ^ (~0L << 35)
                  ^ (~0L << 42)
                  ^ (~0L << 49)
                  ^ (~0L << 56);
          if (x < 0L) {
            if (buffer[tempPos++] < 0L) {
              break fastpath; // Will throw malformedVarint()
            }
          }
        }
        pos = tempPos;
        return x;
      }
      return readRawVarint64SlowPath();
    }

    @Override
    long readRawVarint64SlowPath() throws IOException {
      long result = 0;
      for (int shift = 0; shift < 64; shift += 7) {
        final byte b = readRawByte();
        result |= (long) (b & 0x7F) << shift;
        if ((b & 0x80) == 0) {
          return result;
        }
      }
      throw InvalidProtocolBufferException.malformedVarint();
    }

    @Override
    public int readRawLittleEndian32() throws IOException {
      int tempPos = pos;

      if (bufferSize - tempPos < FIXED32_SIZE) {
        refillBuffer(FIXED32_SIZE);
        tempPos = pos;
      }

      final byte[] buffer = this.buffer;
      pos = tempPos + FIXED32_SIZE;
      return (((buffer[tempPos] & 0xff))
          | ((buffer[tempPos + 1] & 0xff) << 8)
          | ((buffer[tempPos + 2] & 0xff) << 16)
          | ((buffer[tempPos + 3] & 0xff) << 24));
    }

    @Override
    public long readRawLittleEndian64() throws IOException {
      int tempPos = pos;

      if (bufferSize - tempPos < FIXED64_SIZE) {
        refillBuffer(FIXED64_SIZE);
        tempPos = pos;
      }

      final byte[] buffer = this.buffer;
      pos = tempPos + FIXED64_SIZE;
      return (((buffer[tempPos] & 0xffL))
          | ((buffer[tempPos + 1] & 0xffL) << 8)
          | ((buffer[tempPos + 2] & 0xffL) << 16)
          | ((buffer[tempPos + 3] & 0xffL) << 24)
          | ((buffer[tempPos + 4] & 0xffL) << 32)
          | ((buffer[tempPos + 5] & 0xffL) << 40)
          | ((buffer[tempPos + 6] & 0xffL) << 48)
          | ((buffer[tempPos + 7] & 0xffL) << 56));
    }

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

    @Override
    public void enableAliasing(boolean enabled) {
      // TODO(nathanmittler): Ideally we should throw here. Do nothing for backward compatibility.
    }

    @Override
    public void resetSizeCounter() {
      totalBytesRetired = -pos;
    }

    @Override
    public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
      if (byteLimit < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      byteLimit += totalBytesRetired + pos;
      final int oldLimit = currentLimit;
      if (byteLimit > oldLimit) {
        throw InvalidProtocolBufferException.truncatedMessage();
      }
      currentLimit = byteLimit;

      recomputeBufferSizeAfterLimit();

      return oldLimit;
    }

    private void recomputeBufferSizeAfterLimit() {
      bufferSize += bufferSizeAfterLimit;
      final int bufferEnd = totalBytesRetired + bufferSize;
      if (bufferEnd > currentLimit) {
        // Limit is in current buffer.
        bufferSizeAfterLimit = bufferEnd - currentLimit;
        bufferSize -= bufferSizeAfterLimit;
      } else {
        bufferSizeAfterLimit = 0;
      }
    }

    @Override
    public void popLimit(final int oldLimit) {
      currentLimit = oldLimit;
      recomputeBufferSizeAfterLimit();
    }

    @Override
    public int getBytesUntilLimit() {
      if (currentLimit == Integer.MAX_VALUE) {
        return -1;
      }

      final int currentAbsolutePosition = totalBytesRetired + pos;
      return currentLimit - currentAbsolutePosition;
    }

    @Override
    public boolean isAtEnd() throws IOException {
      return pos == bufferSize && !tryRefillBuffer(1);
    }

    @Override
    public int getTotalBytesRead() {
      return totalBytesRetired + pos;
    }

    private interface RefillCallback {
      void onRefill();
    }

    private RefillCallback refillCallback = null;

    /**
     * Reads more bytes from the input, making at least {@code n} bytes available in the buffer.
     * Caller must ensure that the requested space is not yet available, and that the requested
     * space is less than BUFFER_SIZE.
     *
     * @throws InvalidProtocolBufferException The end of the stream or the current limit was
     *     reached.
     */
    private void refillBuffer(int n) throws IOException {
      if (!tryRefillBuffer(n)) {
        // We have to distinguish the exception between sizeLimitExceeded and truncatedMessage. So
        // we just throw an sizeLimitExceeded exception here if it exceeds the sizeLimit
        if (n > sizeLimit - totalBytesRetired - pos) {
          throw InvalidProtocolBufferException.sizeLimitExceeded();
        } else {
          throw InvalidProtocolBufferException.truncatedMessage();
        }
      }
    }

    /**
     * Tries to read more bytes from the input, making at least {@code n} bytes available in the
     * buffer. Caller must ensure that the requested space is not yet available, and that the
     * requested space is less than BUFFER_SIZE.
     *
     * @return {@code true} If the bytes could be made available; {@code false} 1. Current at the
     *     end of the stream 2. The current limit was reached 3. The total size limit was reached
     */
    private boolean tryRefillBuffer(int n) throws IOException {
      if (pos + n <= bufferSize) {
        throw new IllegalStateException(
            "refillBuffer() called when " + n + " bytes were already available in buffer");
      }

      // Check whether the size of total message needs to read is bigger than the size limit.
      // We shouldn't throw an exception here as isAtEnd() function needs to get this function's
      // return as the result.
      if (n > sizeLimit - totalBytesRetired - pos) {
        return false;
      }

      // Shouldn't throw the exception here either.
      if (totalBytesRetired + pos + n > currentLimit) {
        // Oops, we hit a limit.
        return false;
      }

      if (refillCallback != null) {
        refillCallback.onRefill();
      }

      int tempPos = pos;
      if (tempPos > 0) {
        if (bufferSize > tempPos) {
          System.arraycopy(buffer, tempPos, buffer, 0, bufferSize - tempPos);
        }
        totalBytesRetired += tempPos;
        bufferSize -= tempPos;
        pos = 0;
      }

      // Here we should refill the buffer as many bytes as possible.
      int bytesRead =
          input.read(
              buffer,
              bufferSize,
              Math.min(
                  //  the size of allocated but unused bytes in the buffer
                  buffer.length - bufferSize,
                  //  do not exceed the total bytes limit
                  sizeLimit - totalBytesRetired - bufferSize));
      if (bytesRead == 0 || bytesRead < -1 || bytesRead > buffer.length) {
        throw new IllegalStateException(
            input.getClass()
                + "#read(byte[]) returned invalid result: "
                + bytesRead
                + "\nThe InputStream implementation is buggy.");
      }
      if (bytesRead > 0) {
        bufferSize += bytesRead;
        recomputeBufferSizeAfterLimit();
        return (bufferSize >= n) ? true : tryRefillBuffer(n);
      }

      return false;
    }

    @Override
    public byte readRawByte() throws IOException {
      if (pos == bufferSize) {
        refillBuffer(1);
      }
      return buffer[pos++];
    }

    @Override
    public byte[] readRawBytes(final int size) throws IOException {
      final int tempPos = pos;
      if (size <= (bufferSize - tempPos) && size > 0) {
        pos = tempPos + size;
        return Arrays.copyOfRange(buffer, tempPos, tempPos + size);
      } else {
        return readRawBytesSlowPath(size);
      }
    }

    /**
     * Exactly like readRawBytes, but caller must have already checked the fast path: (size <=
     * (bufferSize - pos) && size > 0)
     */
    private byte[] readRawBytesSlowPath(final int size) throws IOException {
      // Attempt to read the data in one byte array when it's safe to do.
      byte[] result = readRawBytesSlowPathOneChunk(size);
      if (result != null) {
        return result;
      }

      final int originalBufferPos = pos;
      final int bufferedBytes = bufferSize - pos;

      // Mark the current buffer consumed.
      totalBytesRetired += bufferSize;
      pos = 0;
      bufferSize = 0;

      // Determine the number of bytes we need to read from the input stream.
      int sizeLeft = size - bufferedBytes;

      // The size is very large. For security reasons we read them in small
      // chunks.
      List<byte[]> chunks = readRawBytesSlowPathRemainingChunks(sizeLeft);

      // OK, got everything.  Now concatenate it all into one buffer.
      final byte[] bytes = new byte[size];

      // Start by copying the leftover bytes from this.buffer.
      System.arraycopy(buffer, originalBufferPos, bytes, 0, bufferedBytes);

      // And now all the chunks.
      int tempPos = bufferedBytes;
      for (final byte[] chunk : chunks) {
        System.arraycopy(chunk, 0, bytes, tempPos, chunk.length);
        tempPos += chunk.length;
      }

      // Done.
      return bytes;
    }

    /**
     * Attempts to read the data in one byte array when it's safe to do. Returns null if the size to
     * read is too large and needs to be allocated in smaller chunks for security reasons.
     */
    private byte[] readRawBytesSlowPathOneChunk(final int size) throws IOException {
      if (size == 0) {
        return Internal.EMPTY_BYTE_ARRAY;
      }
      if (size < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }

      // Integer-overflow-conscious check that the message size so far has not exceeded sizeLimit.
      int currentMessageSize = totalBytesRetired + pos + size;
      if (currentMessageSize - sizeLimit > 0) {
        throw InvalidProtocolBufferException.sizeLimitExceeded();
      }

      // Verify that the message size so far has not exceeded currentLimit.
      if (currentMessageSize > currentLimit) {
        // Read to the end of the stream anyway.
        skipRawBytes(currentLimit - totalBytesRetired - pos);
        throw InvalidProtocolBufferException.truncatedMessage();
      }

      final int bufferedBytes = bufferSize - pos;
      // Determine the number of bytes we need to read from the input stream.
      int sizeLeft = size - bufferedBytes;
      // TODO(nathanmittler): Consider using a value larger than DEFAULT_BUFFER_SIZE.
      if (sizeLeft < DEFAULT_BUFFER_SIZE || sizeLeft <= input.available()) {
        // Either the bytes we need are known to be available, or the required buffer is
        // within an allowed threshold - go ahead and allocate the buffer now.
        final byte[] bytes = new byte[size];

        // Copy all of the buffered bytes to the result buffer.
        System.arraycopy(buffer, pos, bytes, 0, bufferedBytes);
        totalBytesRetired += bufferSize;
        pos = 0;
        bufferSize = 0;

        // Fill the remaining bytes from the input stream.
        int tempPos = bufferedBytes;
        while (tempPos < bytes.length) {
          int n = input.read(bytes, tempPos, size - tempPos);
          if (n == -1) {
            throw InvalidProtocolBufferException.truncatedMessage();
          }
          totalBytesRetired += n;
          tempPos += n;
        }

        return bytes;
      }

      return null;
    }

    /** Reads the remaining data in small chunks from the input stream. */
    private List<byte[]> readRawBytesSlowPathRemainingChunks(int sizeLeft) throws IOException {
      // The size is very large.  For security reasons, we can't allocate the
      // entire byte array yet.  The size comes directly from the input, so a
      // maliciously-crafted message could provide a bogus very large size in
      // order to trick the app into allocating a lot of memory.  We avoid this
      // by allocating and reading only a small chunk at a time, so that the
      // malicious message must actually *be* extremely large to cause
      // problems.  Meanwhile, we limit the allowed size of a message elsewhere.
      final List<byte[]> chunks = new ArrayList<byte[]>();

      while (sizeLeft > 0) {
        // TODO(nathanmittler): Consider using a value larger than DEFAULT_BUFFER_SIZE.
        final byte[] chunk = new byte[Math.min(sizeLeft, DEFAULT_BUFFER_SIZE)];
        int tempPos = 0;
        while (tempPos < chunk.length) {
          final int n = input.read(chunk, tempPos, chunk.length - tempPos);
          if (n == -1) {
            throw InvalidProtocolBufferException.truncatedMessage();
          }
          totalBytesRetired += n;
          tempPos += n;
        }
        sizeLeft -= chunk.length;
        chunks.add(chunk);
      }

      return chunks;
    }

    /**
     * Like readBytes, but caller must have already checked the fast path: (size <= (bufferSize -
     * pos) && size > 0 || size == 0)
     */
    private ByteString readBytesSlowPath(final int size) throws IOException {
      final byte[] result = readRawBytesSlowPathOneChunk(size);
      if (result != null) {
        return ByteString.wrap(result);
      }

      final int originalBufferPos = pos;
      final int bufferedBytes = bufferSize - pos;

      // Mark the current buffer consumed.
      totalBytesRetired += bufferSize;
      pos = 0;
      bufferSize = 0;

      // Determine the number of bytes we need to read from the input stream.
      int sizeLeft = size - bufferedBytes;

      // The size is very large. For security reasons we read them in small
      // chunks.
      List<byte[]> chunks = readRawBytesSlowPathRemainingChunks(sizeLeft);

      // Wrap the byte arrays into a single ByteString.
      List<ByteString> byteStrings = new ArrayList<ByteString>(1 + chunks.size());
      byteStrings.add(ByteString.copyFrom(buffer, originalBufferPos, bufferedBytes));
      for (byte[] chunk : chunks) {
        byteStrings.add(ByteString.wrap(chunk));
      }
      return ByteString.copyFrom(byteStrings);
    }

    @Override
    public void skipRawBytes(final int size) throws IOException {
      if (size <= (bufferSize - pos) && size >= 0) {
        // We have all the bytes we need already.
        pos += size;
      } else {
        skipRawBytesSlowPath(size);
      }
    }

    /**
     * Exactly like skipRawBytes, but caller must have already checked the fast path: (size <=
     * (bufferSize - pos) && size >= 0)
     */
    private void skipRawBytesSlowPath(final int size) throws IOException {
      if (size < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }

      if (totalBytesRetired + pos + size > currentLimit) {
        // Read to the end of the stream anyway.
        skipRawBytes(currentLimit - totalBytesRetired - pos);
        // Then fail.
        throw InvalidProtocolBufferException.truncatedMessage();
      }

      int totalSkipped = 0;
      if (refillCallback == null) {
        // Skipping more bytes than are in the buffer.  First skip what we have.
        totalBytesRetired += pos;
        totalSkipped = bufferSize - pos;
        bufferSize = 0;
        pos = 0;

        try {
          while (totalSkipped < size) {
            int toSkip = size - totalSkipped;
            long skipped = input.skip(toSkip);
            if (skipped < 0 || skipped > toSkip) {
              throw new IllegalStateException(
                  input.getClass()
                      + "#skip returned invalid result: "
                      + skipped
                      + "\nThe InputStream implementation is buggy.");
            } else if (skipped == 0) {
              // The API contract of skip() permits an inputstream to skip zero bytes for any reason
              // it wants. In particular, ByteArrayInputStream will just return zero over and over
              // when it's at the end of its input. In order to actually confirm that we've hit the
              // end of input, we need to issue a read call via the other path.
              break;
            }
            totalSkipped += (int) skipped;
          }
        } finally {
          totalBytesRetired += totalSkipped;
          recomputeBufferSizeAfterLimit();
        }
      }
      if (totalSkipped < size) {
        // Skipping more bytes than are in the buffer.  First skip what we have.
        int tempPos = bufferSize - pos;
        pos = bufferSize;

        // Keep refilling the buffer until we get to the point we wanted to skip to.
        // This has the side effect of ensuring the limits are updated correctly.
        refillBuffer(1);
        while (size - tempPos > bufferSize) {
          tempPos += bufferSize;
          pos = bufferSize;
          refillBuffer(1);
        }

        pos = size - tempPos;
      }
    }
  }

  /**
   * Implementation of {@link CodedInputStream} that uses an {@link Iterable <ByteBuffer>} as the
   * data source. Requires the use of {@code sun.misc.Unsafe} to perform fast reads on the buffer.
   */
  private static final class IterableDirectByteBufferDecoder extends CodedInputStream {
    /** The object that need to decode. */
    private Iterable<ByteBuffer> input;
    /** The {@link Iterator} with type {@link ByteBuffer} of {@code input} */
    private Iterator<ByteBuffer> iterator;
    /** The current ByteBuffer; */
    private ByteBuffer currentByteBuffer;
    /**
     * If {@code true}, indicates that all the buffer are backing a {@link ByteString} and are
     * therefore considered to be an immutable input source.
     */
    private boolean immutable;
    /**
     * If {@code true}, indicates that calls to read {@link ByteString} or {@code byte[]}
     * <strong>may</strong> return slices of the underlying buffer, rather than copies.
     */
    private boolean enableAliasing;
    /** The global total message length limit */
    private int totalBufferSize;
    /** The amount of available data in the input beyond {@link #currentLimit}. */
    private int bufferSizeAfterCurrentLimit;
    /** The absolute position of the end of the current message. */
    private int currentLimit = Integer.MAX_VALUE;
    /** The last tag that was read from this stream. */
    private int lastTag;
    /** Total Bytes have been Read from the {@link Iterable} {@link ByteBuffer} */
    private int totalBytesRead;
    /** The start position offset of the whole message, used as to reset the totalBytesRead */
    private int startOffset;
    /** The current position for current ByteBuffer */
    private long currentByteBufferPos;

    private long currentByteBufferStartPos;
    /**
     * If the current ByteBuffer is unsafe-direct based, currentAddress is the start address of this
     * ByteBuffer; otherwise should be zero.
     */
    private long currentAddress;
    /** The limit position for current ByteBuffer */
    private long currentByteBufferLimit;

    /**
     * The constructor of {@code Iterable<ByteBuffer>} decoder.
     *
     * @param inputBufs The input data.
     * @param size The total size of the input data.
     * @param immutableFlag whether the input data is immutable.
     */
    private IterableDirectByteBufferDecoder(
        Iterable<ByteBuffer> inputBufs, int size, boolean immutableFlag) {
      totalBufferSize = size;
      input = inputBufs;
      iterator = input.iterator();
      immutable = immutableFlag;
      startOffset = totalBytesRead = 0;
      if (size == 0) {
        currentByteBuffer = EMPTY_BYTE_BUFFER;
        currentByteBufferPos = 0;
        currentByteBufferStartPos = 0;
        currentByteBufferLimit = 0;
        currentAddress = 0;
      } else {
        tryGetNextByteBuffer();
      }
    }

    /** To get the next ByteBuffer from {@code input}, and then update the parameters */
    private void getNextByteBuffer() throws InvalidProtocolBufferException {
      if (!iterator.hasNext()) {
        throw InvalidProtocolBufferException.truncatedMessage();
      }
      tryGetNextByteBuffer();
    }

    private void tryGetNextByteBuffer() {
      currentByteBuffer = iterator.next();
      totalBytesRead += (int) (currentByteBufferPos - currentByteBufferStartPos);
      currentByteBufferPos = currentByteBuffer.position();
      currentByteBufferStartPos = currentByteBufferPos;
      currentByteBufferLimit = currentByteBuffer.limit();
      currentAddress = UnsafeUtil.addressOffset(currentByteBuffer);
      currentByteBufferPos += currentAddress;
      currentByteBufferStartPos += currentAddress;
      currentByteBufferLimit += currentAddress;
    }

    @Override
    public int readTag() throws IOException {
      if (isAtEnd()) {
        lastTag = 0;
        return 0;
      }

      lastTag = readRawVarint32();
      if (WireFormat.getTagFieldNumber(lastTag) == 0) {
        // If we actually read zero (or any tag number corresponding to field
        // number zero), that's not a valid tag.
        throw InvalidProtocolBufferException.invalidTag();
      }
      return lastTag;
    }

    @Override
    public void checkLastTagWas(final int value) throws InvalidProtocolBufferException {
      if (lastTag != value) {
        throw InvalidProtocolBufferException.invalidEndTag();
      }
    }

    @Override
    public int getLastTag() {
      return lastTag;
    }

    @Override
    public boolean skipField(final int tag) throws IOException {
      switch (WireFormat.getTagWireType(tag)) {
        case WireFormat.WIRETYPE_VARINT:
          skipRawVarint();
          return true;
        case WireFormat.WIRETYPE_FIXED64:
          skipRawBytes(FIXED64_SIZE);
          return true;
        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
          skipRawBytes(readRawVarint32());
          return true;
        case WireFormat.WIRETYPE_START_GROUP:
          skipMessage();
          checkLastTagWas(
              WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
          return true;
        case WireFormat.WIRETYPE_END_GROUP:
          return false;
        case WireFormat.WIRETYPE_FIXED32:
          skipRawBytes(FIXED32_SIZE);
          return true;
        default:
          throw InvalidProtocolBufferException.invalidWireType();
      }
    }

    @Override
    public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
      switch (WireFormat.getTagWireType(tag)) {
        case WireFormat.WIRETYPE_VARINT:
          {
            long value = readInt64();
            output.writeRawVarint32(tag);
            output.writeUInt64NoTag(value);
            return true;
          }
        case WireFormat.WIRETYPE_FIXED64:
          {
            long value = readRawLittleEndian64();
            output.writeRawVarint32(tag);
            output.writeFixed64NoTag(value);
            return true;
          }
        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
          {
            ByteString value = readBytes();
            output.writeRawVarint32(tag);
            output.writeBytesNoTag(value);
            return true;
          }
        case WireFormat.WIRETYPE_START_GROUP:
          {
            output.writeRawVarint32(tag);
            skipMessage(output);
            int endtag =
                WireFormat.makeTag(
                    WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
            checkLastTagWas(endtag);
            output.writeRawVarint32(endtag);
            return true;
          }
        case WireFormat.WIRETYPE_END_GROUP:
          {
            return false;
          }
        case WireFormat.WIRETYPE_FIXED32:
          {
            int value = readRawLittleEndian32();
            output.writeRawVarint32(tag);
            output.writeFixed32NoTag(value);
            return true;
          }
        default:
          throw InvalidProtocolBufferException.invalidWireType();
      }
    }

    @Override
    public void skipMessage() throws IOException {
      while (true) {
        final int tag = readTag();
        if (tag == 0 || !skipField(tag)) {
          return;
        }
      }
    }

    @Override
    public void skipMessage(CodedOutputStream output) throws IOException {
      while (true) {
        final int tag = readTag();
        if (tag == 0 || !skipField(tag, output)) {
          return;
        }
      }
    }

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

    @Override
    public double readDouble() throws IOException {
      return Double.longBitsToDouble(readRawLittleEndian64());
    }

    @Override
    public float readFloat() throws IOException {
      return Float.intBitsToFloat(readRawLittleEndian32());
    }

    @Override
    public long readUInt64() throws IOException {
      return readRawVarint64();
    }

    @Override
    public long readInt64() throws IOException {
      return readRawVarint64();
    }

    @Override
    public int readInt32() throws IOException {
      return readRawVarint32();
    }

    @Override
    public long readFixed64() throws IOException {
      return readRawLittleEndian64();
    }

    @Override
    public int readFixed32() throws IOException {
      return readRawLittleEndian32();
    }

    @Override
    public boolean readBool() throws IOException {
      return readRawVarint64() != 0;
    }

    @Override
    public String readString() throws IOException {
      final int size = readRawVarint32();
      if (size > 0 && size <= currentByteBufferLimit - currentByteBufferPos) {
        byte[] bytes = new byte[size];
        UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, size);
        String result = new String(bytes, UTF_8);
        currentByteBufferPos += size;
        return result;
      } else if (size > 0 && size <= remaining()) {
        // TODO(yilunchong): To use an underlying bytes[] instead of allocating a new bytes[]
        byte[] bytes = new byte[size];
        readRawBytesTo(bytes, 0, size);
        String result = new String(bytes, UTF_8);
        return result;
      }

      if (size == 0) {
        return "";
      }
      if (size < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      throw InvalidProtocolBufferException.truncatedMessage();
    }

    @Override
    public String readStringRequireUtf8() throws IOException {
      final int size = readRawVarint32();
      if (size > 0 && size <= currentByteBufferLimit - currentByteBufferPos) {
        final int bufferPos = (int) (currentByteBufferPos - currentByteBufferStartPos);
        String result = Utf8.decodeUtf8(currentByteBuffer, bufferPos, size);
        currentByteBufferPos += size;
        return result;
      }
      if (size >= 0 && size <= remaining()) {
        byte[] bytes = new byte[size];
        readRawBytesTo(bytes, 0, size);
        return Utf8.decodeUtf8(bytes, 0, size);
      }

      if (size == 0) {
        return "";
      }
      if (size <= 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      throw InvalidProtocolBufferException.truncatedMessage();
    }

    @Override
    public void readGroup(
        final int fieldNumber,
        final MessageLite.Builder builder,
        final ExtensionRegistryLite extensionRegistry)
        throws IOException {
      if (recursionDepth >= recursionLimit) {
        throw InvalidProtocolBufferException.recursionLimitExceeded();
      }
      ++recursionDepth;
      builder.mergeFrom(this, extensionRegistry);
      checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
      --recursionDepth;
    }


    @Override
    public <T extends MessageLite> T readGroup(
        final int fieldNumber,
        final Parser<T> parser,
        final ExtensionRegistryLite extensionRegistry)
        throws IOException {
      if (recursionDepth >= recursionLimit) {
        throw InvalidProtocolBufferException.recursionLimitExceeded();
      }
      ++recursionDepth;
      T result = parser.parsePartialFrom(this, extensionRegistry);
      checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
      --recursionDepth;
      return result;
    }

    @Deprecated
    @Override
    public void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
        throws IOException {
      readGroup(fieldNumber, builder, ExtensionRegistryLite.getEmptyRegistry());
    }

    @Override
    public void readMessage(
        final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
        throws IOException {
      final int length = readRawVarint32();
      if (recursionDepth >= recursionLimit) {
        throw InvalidProtocolBufferException.recursionLimitExceeded();
      }
      final int oldLimit = pushLimit(length);
      ++recursionDepth;
      builder.mergeFrom(this, extensionRegistry);
      checkLastTagWas(0);
      --recursionDepth;
      popLimit(oldLimit);
    }


    @Override
    public <T extends MessageLite> T readMessage(
        final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException {
      int length = readRawVarint32();
      if (recursionDepth >= recursionLimit) {
        throw InvalidProtocolBufferException.recursionLimitExceeded();
      }
      final int oldLimit = pushLimit(length);
      ++recursionDepth;
      T result = parser.parsePartialFrom(this, extensionRegistry);
      checkLastTagWas(0);
      --recursionDepth;
      popLimit(oldLimit);
      return result;
    }

    @Override
    public ByteString readBytes() throws IOException {
      final int size = readRawVarint32();
      if (size > 0 && size <= currentByteBufferLimit - currentByteBufferPos) {
        if (immutable && enableAliasing) {
          final int idx = (int) (currentByteBufferPos - currentAddress);
          final ByteString result = ByteString.wrap(slice(idx, idx + size));
          currentByteBufferPos += size;
          return result;
        } else {
          byte[] bytes;
          bytes = new byte[size];
          UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, size);
          currentByteBufferPos += size;
          return ByteString.wrap(bytes);
        }
      } else if (size > 0 && size <= remaining()) {
        byte[] temp = new byte[size];
        readRawBytesTo(temp, 0, size);
        return ByteString.wrap(temp);
      }

      if (size == 0) {
        return ByteString.EMPTY;
      }
      if (size < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      throw InvalidProtocolBufferException.truncatedMessage();
    }

    @Override
    public byte[] readByteArray() throws IOException {
      return readRawBytes(readRawVarint32());
    }

    @Override
    public ByteBuffer readByteBuffer() throws IOException {
      final int size = readRawVarint32();
      if (size > 0 && size <= currentRemaining()) {
        if (!immutable && enableAliasing) {
          currentByteBufferPos += size;
          return slice(
              (int) (currentByteBufferPos - currentAddress - size),
              (int) (currentByteBufferPos - currentAddress));
        } else {
          byte[] bytes = new byte[size];
          UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, size);
          currentByteBufferPos += size;
          return ByteBuffer.wrap(bytes);
        }
      } else if (size > 0 && size <= remaining()) {
        byte[] temp = new byte[size];
        readRawBytesTo(temp, 0, size);
        return ByteBuffer.wrap(temp);
      }

      if (size == 0) {
        return EMPTY_BYTE_BUFFER;
      }
      if (size < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      throw InvalidProtocolBufferException.truncatedMessage();
    }

    @Override
    public int readUInt32() throws IOException {
      return readRawVarint32();
    }

    @Override
    public int readEnum() throws IOException {
      return readRawVarint32();
    }

    @Override
    public int readSFixed32() throws IOException {
      return readRawLittleEndian32();
    }

    @Override
    public long readSFixed64() throws IOException {
      return readRawLittleEndian64();
    }

    @Override
    public int readSInt32() throws IOException {
      return decodeZigZag32(readRawVarint32());
    }

    @Override
    public long readSInt64() throws IOException {
      return decodeZigZag64(readRawVarint64());
    }

    @Override
    public int readRawVarint32() throws IOException {
      fastpath:
      {
        long tempPos = currentByteBufferPos;

        if (currentByteBufferLimit == currentByteBufferPos) {
          break fastpath;
        }

        int x;
        if ((x = UnsafeUtil.getByte(tempPos++)) >= 0) {
          currentByteBufferPos++;
          return x;
        } else if (currentByteBufferLimit - currentByteBufferPos < 10) {
          break fastpath;
        } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 7)) < 0) {
          x ^= (~0 << 7);
        } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 14)) >= 0) {
          x ^= (~0 << 7) ^ (~0 << 14);
        } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 21)) < 0) {
          x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
        } else {
          int y = UnsafeUtil.getByte(tempPos++);
          x ^= y << 28;
          x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
          if (y < 0
              && UnsafeUtil.getByte(tempPos++) < 0
              && UnsafeUtil.getByte(tempPos++) < 0
              && UnsafeUtil.getByte(tempPos++) < 0
              && UnsafeUtil.getByte(tempPos++) < 0
              && UnsafeUtil.getByte(tempPos++) < 0) {
            break fastpath; // Will throw malformedVarint()
          }
        }
        currentByteBufferPos = tempPos;
        return x;
      }
      return (int) readRawVarint64SlowPath();
    }

    @Override
    public long readRawVarint64() throws IOException {
      fastpath:
      {
        long tempPos = currentByteBufferPos;

        if (currentByteBufferLimit == currentByteBufferPos) {
          break fastpath;
        }

        long x;
        int y;
        if ((y = UnsafeUtil.getByte(tempPos++)) >= 0) {
          currentByteBufferPos++;
          return y;
        } else if (currentByteBufferLimit - currentByteBufferPos < 10) {
          break fastpath;
        } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 7)) < 0) {
          x = y ^ (~0 << 7);
        } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 14)) >= 0) {
          x = y ^ ((~0 << 7) ^ (~0 << 14));
        } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 21)) < 0) {
          x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
        } else if ((x = y ^ ((long) UnsafeUtil.getByte(tempPos++) << 28)) >= 0L) {
          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
        } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 35)) < 0L) {
          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
        } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 42)) >= 0L) {
          x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
        } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 49)) < 0L) {
          x ^=
              (~0L << 7)
                  ^ (~0L << 14)
                  ^ (~0L << 21)
                  ^ (~0L << 28)
                  ^ (~0L << 35)
                  ^ (~0L << 42)
                  ^ (~0L << 49);
        } else {
          x ^= ((long) UnsafeUtil.getByte(tempPos++) << 56);
          x ^=
              (~0L << 7)
                  ^ (~0L << 14)
                  ^ (~0L << 21)
                  ^ (~0L << 28)
                  ^ (~0L << 35)
                  ^ (~0L << 42)
                  ^ (~0L << 49)
                  ^ (~0L << 56);
          if (x < 0L) {
            if (UnsafeUtil.getByte(tempPos++) < 0L) {
              break fastpath; // Will throw malformedVarint()
            }
          }
        }
        currentByteBufferPos = tempPos;
        return x;
      }
      return readRawVarint64SlowPath();
    }

    @Override
    long readRawVarint64SlowPath() throws IOException {
      long result = 0;
      for (int shift = 0; shift < 64; shift += 7) {
        final byte b = readRawByte();
        result |= (long) (b & 0x7F) << shift;
        if ((b & 0x80) == 0) {
          return result;
        }
      }
      throw InvalidProtocolBufferException.malformedVarint();
    }

    @Override
    public int readRawLittleEndian32() throws IOException {
      if (currentRemaining() >= FIXED32_SIZE) {
        long tempPos = currentByteBufferPos;
        currentByteBufferPos += FIXED32_SIZE;
        return (((UnsafeUtil.getByte(tempPos) & 0xff))
            | ((UnsafeUtil.getByte(tempPos + 1) & 0xff) << 8)
            | ((UnsafeUtil.getByte(tempPos + 2) & 0xff) << 16)
            | ((UnsafeUtil.getByte(tempPos + 3) & 0xff) << 24));
      }
      return ((readRawByte() & 0xff)
          | ((readRawByte() & 0xff) << 8)
          | ((readRawByte() & 0xff) << 16)
          | ((readRawByte() & 0xff) << 24));
    }

    @Override
    public long readRawLittleEndian64() throws IOException {
      if (currentRemaining() >= FIXED64_SIZE) {
        long tempPos = currentByteBufferPos;
        currentByteBufferPos += FIXED64_SIZE;
        return (((UnsafeUtil.getByte(tempPos) & 0xffL))
            | ((UnsafeUtil.getByte(tempPos + 1) & 0xffL) << 8)
            | ((UnsafeUtil.getByte(tempPos + 2) & 0xffL) << 16)
            | ((UnsafeUtil.getByte(tempPos + 3) & 0xffL) << 24)
            | ((UnsafeUtil.getByte(tempPos + 4) & 0xffL) << 32)
            | ((UnsafeUtil.getByte(tempPos + 5) & 0xffL) << 40)
            | ((UnsafeUtil.getByte(tempPos + 6) & 0xffL) << 48)
            | ((UnsafeUtil.getByte(tempPos + 7) & 0xffL) << 56));
      }
      return ((readRawByte() & 0xffL)
          | ((readRawByte() & 0xffL) << 8)
          | ((readRawByte() & 0xffL) << 16)
          | ((readRawByte() & 0xffL) << 24)
          | ((readRawByte() & 0xffL) << 32)
          | ((readRawByte() & 0xffL) << 40)
          | ((readRawByte() & 0xffL) << 48)
          | ((readRawByte() & 0xffL) << 56));
    }

    @Override
    public void enableAliasing(boolean enabled) {
      this.enableAliasing = enabled;
    }

    @Override
    public void resetSizeCounter() {
      startOffset = (int) (totalBytesRead + currentByteBufferPos - currentByteBufferStartPos);
    }

    @Override
    public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
      if (byteLimit < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      byteLimit += getTotalBytesRead();
      final int oldLimit = currentLimit;
      if (byteLimit > oldLimit) {
        throw InvalidProtocolBufferException.truncatedMessage();
      }
      currentLimit = byteLimit;

      recomputeBufferSizeAfterLimit();

      return oldLimit;
    }

    private void recomputeBufferSizeAfterLimit() {
      totalBufferSize += bufferSizeAfterCurrentLimit;
      final int bufferEnd = totalBufferSize - startOffset;
      if (bufferEnd > currentLimit) {
        // Limit is in current buffer.
        bufferSizeAfterCurrentLimit = bufferEnd - currentLimit;
        totalBufferSize -= bufferSizeAfterCurrentLimit;
      } else {
        bufferSizeAfterCurrentLimit = 0;
      }
    }

    @Override
    public void popLimit(final int oldLimit) {
      currentLimit = oldLimit;
      recomputeBufferSizeAfterLimit();
    }

    @Override
    public int getBytesUntilLimit() {
      if (currentLimit == Integer.MAX_VALUE) {
        return -1;
      }

      return currentLimit - getTotalBytesRead();
    }

    @Override
    public boolean isAtEnd() throws IOException {
      return totalBytesRead + currentByteBufferPos - currentByteBufferStartPos == totalBufferSize;
    }

    @Override
    public int getTotalBytesRead() {
      return (int)
          (totalBytesRead - startOffset + currentByteBufferPos - currentByteBufferStartPos);
    }

    @Override
    public byte readRawByte() throws IOException {
      if (currentRemaining() == 0) {
        getNextByteBuffer();
      }
      return UnsafeUtil.getByte(currentByteBufferPos++);
    }

    @Override
    public byte[] readRawBytes(final int length) throws IOException {
      if (length >= 0 && length <= currentRemaining()) {
        byte[] bytes = new byte[length];
        UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, length);
        currentByteBufferPos += length;
        return bytes;
      }
      if (length >= 0 && length <= remaining()) {
        byte[] bytes = new byte[length];
        readRawBytesTo(bytes, 0, length);
        return bytes;
      }

      if (length <= 0) {
        if (length == 0) {
          return EMPTY_BYTE_ARRAY;
        } else {
          throw InvalidProtocolBufferException.negativeSize();
        }
      }

      throw InvalidProtocolBufferException.truncatedMessage();
    }

    /**
     * Try to get raw bytes from {@code input} with the size of {@code length} and copy to {@code
     * bytes} array. If the size is bigger than the number of remaining bytes in the input, then
     * throw {@code truncatedMessage} exception.
     *
     * @param bytes
     * @param offset
     * @param length
     * @throws IOException
     */
    private void readRawBytesTo(byte[] bytes, int offset, final int length) throws IOException {
      if (length >= 0 && length <= remaining()) {
        int l = length;
        while (l > 0) {
          if (currentRemaining() == 0) {
            getNextByteBuffer();
          }
          int bytesToCopy = Math.min(l, (int) currentRemaining());
          UnsafeUtil.copyMemory(currentByteBufferPos, bytes, length - l + offset, bytesToCopy);
          l -= bytesToCopy;
          currentByteBufferPos += bytesToCopy;
        }
        return;
      }

      if (length <= 0) {
        if (length == 0) {
          return;
        } else {
          throw InvalidProtocolBufferException.negativeSize();
        }
      }
      throw InvalidProtocolBufferException.truncatedMessage();
    }

    @Override
    public void skipRawBytes(final int length) throws IOException {
      if (length >= 0
          && length
              <= (totalBufferSize
                  - totalBytesRead
                  - currentByteBufferPos
                  + currentByteBufferStartPos)) {
        // We have all the bytes we need already.
        int l = length;
        while (l > 0) {
          if (currentRemaining() == 0) {
            getNextByteBuffer();
          }
          int rl = Math.min(l, (int) currentRemaining());
          l -= rl;
          currentByteBufferPos += rl;
        }
        return;
      }

      if (length < 0) {
        throw InvalidProtocolBufferException.negativeSize();
      }
      throw InvalidProtocolBufferException.truncatedMessage();
    }

    // TODO: optimize to fastpath
    private void skipRawVarint() throws IOException {
      for (int i = 0; i < MAX_VARINT_SIZE; i++) {
        if (readRawByte() >= 0) {
          return;
        }
      }
      throw InvalidProtocolBufferException.malformedVarint();
    }

    /**
     * Try to get the number of remaining bytes in {@code input}.
     *
     * @return the number of remaining bytes in {@code input}.
     */
    private int remaining() {
      return (int)
          (totalBufferSize - totalBytesRead - currentByteBufferPos + currentByteBufferStartPos);
    }

    /**
     * Try to get the number of remaining bytes in {@code currentByteBuffer}.
     *
     * @return the number of remaining bytes in {@code currentByteBuffer}
     */
    private long currentRemaining() {
      return (currentByteBufferLimit - currentByteBufferPos);
    }

    private ByteBuffer slice(int begin, int end) throws IOException {
      int prevPos = currentByteBuffer.position();
      int prevLimit = currentByteBuffer.limit();
      try {
        currentByteBuffer.position(begin);
        currentByteBuffer.limit(end);
        return currentByteBuffer.slice();
      } catch (IllegalArgumentException e) {
        throw InvalidProtocolBufferException.truncatedMessage();
      } finally {
        currentByteBuffer.position(prevPos);
        currentByteBuffer.limit(prevLimit);
      }
    }
  }
}
