Imported Upstream version 3.8.0
[platform/upstream/protobuf.git] / java / core / src / main / java / com / google / protobuf / CodedInputStream.java
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 package com.google.protobuf;
32
33 import static com.google.protobuf.Internal.EMPTY_BYTE_ARRAY;
34 import static com.google.protobuf.Internal.EMPTY_BYTE_BUFFER;
35 import static com.google.protobuf.Internal.UTF_8;
36 import static com.google.protobuf.Internal.checkNotNull;
37 import static com.google.protobuf.WireFormat.FIXED32_SIZE;
38 import static com.google.protobuf.WireFormat.FIXED64_SIZE;
39 import static com.google.protobuf.WireFormat.MAX_VARINT_SIZE;
40
41 import java.io.ByteArrayOutputStream;
42 import java.io.IOException;
43 import java.io.InputStream;
44 import java.nio.ByteBuffer;
45 import java.util.ArrayList;
46 import java.util.Arrays;
47 import java.util.Iterator;
48 import java.util.List;
49
50 /**
51  * Reads and decodes protocol message fields.
52  *
53  * <p>This class contains two kinds of methods: methods that read specific protocol message
54  * constructs and field types (e.g. {@link #readTag()} and {@link #readInt32()}) and methods that
55  * read low-level values (e.g. {@link #readRawVarint32()} and {@link #readRawBytes}). If you are
56  * reading encoded protocol messages, you should use the former methods, but if you are reading some
57  * other format of your own design, use the latter.
58  *
59  * @author kenton@google.com Kenton Varda
60  */
61 public abstract class CodedInputStream {
62   private static final int DEFAULT_BUFFER_SIZE = 4096;
63   private static final int DEFAULT_RECURSION_LIMIT = 100;
64   // Integer.MAX_VALUE == 0x7FFFFFF == INT_MAX from limits.h
65   private static final int DEFAULT_SIZE_LIMIT = Integer.MAX_VALUE;
66
67   /** Visible for subclasses. See setRecursionLimit() */
68   int recursionDepth;
69
70   int recursionLimit = DEFAULT_RECURSION_LIMIT;
71
72   /** Visible for subclasses. See setSizeLimit() */
73   int sizeLimit = DEFAULT_SIZE_LIMIT;
74
75   /** Used to adapt to the experimental {@link Reader} interface. */
76   CodedInputStreamReader wrapper;
77
78   /** Create a new CodedInputStream wrapping the given InputStream. */
79   public static CodedInputStream newInstance(final InputStream input) {
80     return newInstance(input, DEFAULT_BUFFER_SIZE);
81   }
82
83   /** Create a new CodedInputStream wrapping the given InputStream, with a specified buffer size. */
84   public static CodedInputStream newInstance(final InputStream input, int bufferSize) {
85     if (bufferSize <= 0) {
86       throw new IllegalArgumentException("bufferSize must be > 0");
87     }
88     if (input == null) {
89       // TODO(nathanmittler): Ideally we should throw here. This is done for backward compatibility.
90       return newInstance(EMPTY_BYTE_ARRAY);
91     }
92     return new StreamDecoder(input, bufferSize);
93   }
94
95   /** Create a new CodedInputStream wrapping the given {@code Iterable <ByteBuffer>}. */
96   public static CodedInputStream newInstance(final Iterable<ByteBuffer> input) {
97     if (!UnsafeDirectNioDecoder.isSupported()) {
98       return newInstance(new IterableByteBufferInputStream(input));
99     }
100     return newInstance(input, false);
101   }
102
103   /** Create a new CodedInputStream wrapping the given {@code Iterable <ByteBuffer>}. */
104   static CodedInputStream newInstance(
105       final Iterable<ByteBuffer> bufs, final boolean bufferIsImmutable) {
106     // flag is to check the type of input's ByteBuffers.
107     // flag equals 1: all ByteBuffers have array.
108     // flag equals 2: all ByteBuffers are direct ByteBuffers.
109     // flag equals 3: some ByteBuffers are direct and some have array.
110     // flag greater than 3: other cases.
111     int flag = 0;
112     // Total size of the input
113     int totalSize = 0;
114     for (ByteBuffer buf : bufs) {
115       totalSize += buf.remaining();
116       if (buf.hasArray()) {
117         flag |= 1;
118       } else if (buf.isDirect()) {
119         flag |= 2;
120       } else {
121         flag |= 4;
122       }
123     }
124     if (flag == 2) {
125       return new IterableDirectByteBufferDecoder(bufs, totalSize, bufferIsImmutable);
126     } else {
127       // TODO(yilunchong): add another decoders to deal case 1 and 3.
128       return newInstance(new IterableByteBufferInputStream(bufs));
129     }
130   }
131
132   /** Create a new CodedInputStream wrapping the given byte array. */
133   public static CodedInputStream newInstance(final byte[] buf) {
134     return newInstance(buf, 0, buf.length);
135   }
136
137   /** Create a new CodedInputStream wrapping the given byte array slice. */
138   public static CodedInputStream newInstance(final byte[] buf, final int off, final int len) {
139     return newInstance(buf, off, len, /* bufferIsImmutable= */ false);
140   }
141
142   /** Create a new CodedInputStream wrapping the given byte array slice. */
143   static CodedInputStream newInstance(
144       final byte[] buf, final int off, final int len, final boolean bufferIsImmutable) {
145     ArrayDecoder result = new ArrayDecoder(buf, off, len, bufferIsImmutable);
146     try {
147       // Some uses of CodedInputStream can be more efficient if they know
148       // exactly how many bytes are available.  By pushing the end point of the
149       // buffer as a limit, we allow them to get this information via
150       // getBytesUntilLimit().  Pushing a limit that we know is at the end of
151       // the stream can never hurt, since we can never past that point anyway.
152       result.pushLimit(len);
153     } catch (InvalidProtocolBufferException ex) {
154       // The only reason pushLimit() might throw an exception here is if len
155       // is negative. Normally pushLimit()'s parameter comes directly off the
156       // wire, so it's important to catch exceptions in case of corrupt or
157       // malicious data. However, in this case, we expect that len is not a
158       // user-supplied value, so we can assume that it being negative indicates
159       // a programming error. Therefore, throwing an unchecked exception is
160       // appropriate.
161       throw new IllegalArgumentException(ex);
162     }
163     return result;
164   }
165
166   /**
167    * Create a new CodedInputStream wrapping the given ByteBuffer. The data starting from the
168    * ByteBuffer's current position to its limit will be read. The returned CodedInputStream may or
169    * may not share the underlying data in the ByteBuffer, therefore the ByteBuffer cannot be changed
170    * while the CodedInputStream is in use. Note that the ByteBuffer's position won't be changed by
171    * this function. Concurrent calls with the same ByteBuffer object are safe if no other thread is
172    * trying to alter the ByteBuffer's status.
173    */
174   public static CodedInputStream newInstance(ByteBuffer buf) {
175     return newInstance(buf, /* bufferIsImmutable= */ false);
176   }
177
178   /** Create a new CodedInputStream wrapping the given buffer. */
179   static CodedInputStream newInstance(ByteBuffer buf, boolean bufferIsImmutable) {
180     if (buf.hasArray()) {
181       return newInstance(
182           buf.array(), buf.arrayOffset() + buf.position(), buf.remaining(), bufferIsImmutable);
183     }
184
185     if (buf.isDirect() && UnsafeDirectNioDecoder.isSupported()) {
186       return new UnsafeDirectNioDecoder(buf, bufferIsImmutable);
187     }
188
189     // The buffer is non-direct and does not expose the underlying array. Using the ByteBuffer API
190     // to access individual bytes is very slow, so just copy the buffer to an array.
191     // TODO(nathanmittler): Re-evaluate with Java 9
192     byte[] buffer = new byte[buf.remaining()];
193     buf.duplicate().get(buffer);
194     return newInstance(buffer, 0, buffer.length, true);
195   }
196
197   /** Disable construction/inheritance outside of this class. */
198   private CodedInputStream() {}
199
200   // -----------------------------------------------------------------
201
202   /**
203    * Attempt to read a field tag, returning zero if we have reached EOF. Protocol message parsers
204    * use this to read tags, since a protocol message may legally end wherever a tag occurs, and zero
205    * is not a valid tag number.
206    */
207   public abstract int readTag() throws IOException;
208
209   /**
210    * Verifies that the last call to readTag() returned the given tag value. This is used to verify
211    * that a nested group ended with the correct end tag.
212    *
213    * @throws InvalidProtocolBufferException {@code value} does not match the last tag.
214    */
215   public abstract void checkLastTagWas(final int value) throws InvalidProtocolBufferException;
216
217   public abstract int getLastTag();
218
219   /**
220    * Reads and discards a single field, given its tag value.
221    *
222    * @return {@code false} if the tag is an endgroup tag, in which case nothing is skipped.
223    *     Otherwise, returns {@code true}.
224    */
225   public abstract boolean skipField(final int tag) throws IOException;
226
227   /**
228    * Reads a single field and writes it to output in wire format, given its tag value.
229    *
230    * @return {@code false} if the tag is an endgroup tag, in which case nothing is skipped.
231    *     Otherwise, returns {@code true}.
232    * @deprecated use {@code UnknownFieldSet} or {@code UnknownFieldSetLite} to skip to an output
233    *     stream.
234    */
235   @Deprecated
236   public abstract boolean skipField(final int tag, final CodedOutputStream output)
237       throws IOException;
238
239   /**
240    * Reads and discards an entire message. This will read either until EOF or until an endgroup tag,
241    * whichever comes first.
242    */
243   public abstract void skipMessage() throws IOException;
244
245   /**
246    * Reads an entire message and writes it to output in wire format. This will read either until EOF
247    * or until an endgroup tag, whichever comes first.
248    */
249   public abstract void skipMessage(CodedOutputStream output) throws IOException;
250
251
252   // -----------------------------------------------------------------
253
254   /** Read a {@code double} field value from the stream. */
255   public abstract double readDouble() throws IOException;
256
257   /** Read a {@code float} field value from the stream. */
258   public abstract float readFloat() throws IOException;
259
260   /** Read a {@code uint64} field value from the stream. */
261   public abstract long readUInt64() throws IOException;
262
263   /** Read an {@code int64} field value from the stream. */
264   public abstract long readInt64() throws IOException;
265
266   /** Read an {@code int32} field value from the stream. */
267   public abstract int readInt32() throws IOException;
268
269   /** Read a {@code fixed64} field value from the stream. */
270   public abstract long readFixed64() throws IOException;
271
272   /** Read a {@code fixed32} field value from the stream. */
273   public abstract int readFixed32() throws IOException;
274
275   /** Read a {@code bool} field value from the stream. */
276   public abstract boolean readBool() throws IOException;
277
278   /**
279    * Read a {@code string} field value from the stream. If the stream contains malformed UTF-8,
280    * replace the offending bytes with the standard UTF-8 replacement character.
281    */
282   public abstract String readString() throws IOException;
283
284   /**
285    * Read a {@code string} field value from the stream. If the stream contains malformed UTF-8,
286    * throw exception {@link InvalidProtocolBufferException}.
287    */
288   public abstract String readStringRequireUtf8() throws IOException;
289
290   /** Read a {@code group} field value from the stream. */
291   public abstract void readGroup(
292       final int fieldNumber,
293       final MessageLite.Builder builder,
294       final ExtensionRegistryLite extensionRegistry)
295       throws IOException;
296
297
298   /** Read a {@code group} field value from the stream. */
299   public abstract <T extends MessageLite> T readGroup(
300       final int fieldNumber, final Parser<T> parser, final ExtensionRegistryLite extensionRegistry)
301       throws IOException;
302
303   /**
304    * Reads a {@code group} field value from the stream and merges it into the given {@link
305    * UnknownFieldSet}.
306    *
307    * @deprecated UnknownFieldSet.Builder now implements MessageLite.Builder, so you can just call
308    *     {@link #readGroup}.
309    */
310   @Deprecated
311   public abstract void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
312       throws IOException;
313
314   /** Read an embedded message field value from the stream. */
315   public abstract void readMessage(
316       final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
317       throws IOException;
318
319
320   /** Read an embedded message field value from the stream. */
321   public abstract <T extends MessageLite> T readMessage(
322       final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException;
323
324   /** Read a {@code bytes} field value from the stream. */
325   public abstract ByteString readBytes() throws IOException;
326
327   /** Read a {@code bytes} field value from the stream. */
328   public abstract byte[] readByteArray() throws IOException;
329
330   /** Read a {@code bytes} field value from the stream. */
331   public abstract ByteBuffer readByteBuffer() throws IOException;
332
333   /** Read a {@code uint32} field value from the stream. */
334   public abstract int readUInt32() throws IOException;
335
336   /**
337    * Read an enum field value from the stream. Caller is responsible for converting the numeric
338    * value to an actual enum.
339    */
340   public abstract int readEnum() throws IOException;
341
342   /** Read an {@code sfixed32} field value from the stream. */
343   public abstract int readSFixed32() throws IOException;
344
345   /** Read an {@code sfixed64} field value from the stream. */
346   public abstract long readSFixed64() throws IOException;
347
348   /** Read an {@code sint32} field value from the stream. */
349   public abstract int readSInt32() throws IOException;
350
351   /** Read an {@code sint64} field value from the stream. */
352   public abstract long readSInt64() throws IOException;
353
354   // =================================================================
355
356   /** Read a raw Varint from the stream. If larger than 32 bits, discard the upper bits. */
357   public abstract int readRawVarint32() throws IOException;
358
359   /** Read a raw Varint from the stream. */
360   public abstract long readRawVarint64() throws IOException;
361
362   /** Variant of readRawVarint64 for when uncomfortably close to the limit. */
363   /* Visible for testing */
364   abstract long readRawVarint64SlowPath() throws IOException;
365
366   /** Read a 32-bit little-endian integer from the stream. */
367   public abstract int readRawLittleEndian32() throws IOException;
368
369   /** Read a 64-bit little-endian integer from the stream. */
370   public abstract long readRawLittleEndian64() throws IOException;
371
372   // -----------------------------------------------------------------
373
374   /**
375    * Enables {@link ByteString} aliasing of the underlying buffer, trading off on buffer pinning for
376    * data copies. Only valid for buffer-backed streams.
377    */
378   public abstract void enableAliasing(boolean enabled);
379
380   /**
381    * Set the maximum message recursion depth. In order to prevent malicious messages from causing
382    * stack overflows, {@code CodedInputStream} limits how deeply messages may be nested. The default
383    * limit is 100.
384    *
385    * @return the old limit.
386    */
387   public final int setRecursionLimit(final int limit) {
388     if (limit < 0) {
389       throw new IllegalArgumentException("Recursion limit cannot be negative: " + limit);
390     }
391     final int oldLimit = recursionLimit;
392     recursionLimit = limit;
393     return oldLimit;
394   }
395
396   /**
397    * Only valid for {@link InputStream}-backed streams.
398    *
399    * <p>Set the maximum message size. In order to prevent malicious messages from exhausting memory
400    * or causing integer overflows, {@code CodedInputStream} limits how large a message may be. The
401    * default limit is {@code Integer.MAX_INT}. You should set this limit as small as you can without
402    * harming your app's functionality. Note that size limits only apply when reading from an {@code
403    * InputStream}, not when constructed around a raw byte array.
404    *
405    * <p>If you want to read several messages from a single CodedInputStream, you could call {@link
406    * #resetSizeCounter()} after each one to avoid hitting the size limit.
407    *
408    * @return the old limit.
409    */
410   public final int setSizeLimit(final int limit) {
411     if (limit < 0) {
412       throw new IllegalArgumentException("Size limit cannot be negative: " + limit);
413     }
414     final int oldLimit = sizeLimit;
415     sizeLimit = limit;
416     return oldLimit;
417   }
418
419   private boolean shouldDiscardUnknownFields = false;
420
421   /**
422    * Sets this {@code CodedInputStream} to discard unknown fields. Only applies to full runtime
423    * messages; lite messages will always preserve unknowns.
424    *
425    * <p>Note calling this function alone will have NO immediate effect on the underlying input data.
426    * The unknown fields will be discarded during parsing. This affects both Proto2 and Proto3 full
427    * runtime.
428    */
429   final void discardUnknownFields() {
430     shouldDiscardUnknownFields = true;
431   }
432
433   /**
434    * Reverts the unknown fields preservation behavior for Proto2 and Proto3 full runtime to their
435    * default.
436    */
437   final void unsetDiscardUnknownFields() {
438     shouldDiscardUnknownFields = false;
439   }
440
441   /**
442    * Whether unknown fields in this input stream should be discarded during parsing into full
443    * runtime messages.
444    */
445   final boolean shouldDiscardUnknownFields() {
446     return shouldDiscardUnknownFields;
447   }
448
449   /**
450    * Resets the current size counter to zero (see {@link #setSizeLimit(int)}). Only valid for {@link
451    * InputStream}-backed streams.
452    */
453   public abstract void resetSizeCounter();
454
455   /**
456    * Sets {@code currentLimit} to (current position) + {@code byteLimit}. This is called when
457    * descending into a length-delimited embedded message.
458    *
459    * <p>Note that {@code pushLimit()} does NOT affect how many bytes the {@code CodedInputStream}
460    * reads from an underlying {@code InputStream} when refreshing its buffer. If you need to prevent
461    * reading past a certain point in the underlying {@code InputStream} (e.g. because you expect it
462    * to contain more data after the end of the message which you need to handle differently) then
463    * you must place a wrapper around your {@code InputStream} which limits the amount of data that
464    * can be read from it.
465    *
466    * @return the old limit.
467    */
468   public abstract int pushLimit(int byteLimit) throws InvalidProtocolBufferException;
469
470   /**
471    * Discards the current limit, returning to the previous limit.
472    *
473    * @param oldLimit The old limit, as returned by {@code pushLimit}.
474    */
475   public abstract void popLimit(final int oldLimit);
476
477   /**
478    * Returns the number of bytes to be read before the current limit. If no limit is set, returns
479    * -1.
480    */
481   public abstract int getBytesUntilLimit();
482
483   /**
484    * Returns true if the stream has reached the end of the input. This is the case if either the end
485    * of the underlying input source has been reached or if the stream has reached a limit created
486    * using {@link #pushLimit(int)}.
487    */
488   public abstract boolean isAtEnd() throws IOException;
489
490   /**
491    * The total bytes read up to the current position. Calling {@link #resetSizeCounter()} resets
492    * this value to zero.
493    */
494   public abstract int getTotalBytesRead();
495
496   /**
497    * Read one byte from the input.
498    *
499    * @throws InvalidProtocolBufferException The end of the stream or the current limit was reached.
500    */
501   public abstract byte readRawByte() throws IOException;
502
503   /**
504    * Read a fixed size of bytes from the input.
505    *
506    * @throws InvalidProtocolBufferException The end of the stream or the current limit was reached.
507    */
508   public abstract byte[] readRawBytes(final int size) throws IOException;
509
510   /**
511    * Reads and discards {@code size} bytes.
512    *
513    * @throws InvalidProtocolBufferException The end of the stream or the current limit was reached.
514    */
515   public abstract void skipRawBytes(final int size) throws IOException;
516
517   /**
518    * Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers into values that can be
519    * efficiently encoded with varint. (Otherwise, negative values must be sign-extended to 64 bits
520    * to be varint encoded, thus always taking 10 bytes on the wire.)
521    *
522    * @param n An unsigned 32-bit integer, stored in a signed int because Java has no explicit
523    *     unsigned support.
524    * @return A signed 32-bit integer.
525    */
526   public static int decodeZigZag32(final int n) {
527     return (n >>> 1) ^ -(n & 1);
528   }
529
530   /**
531    * Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers into values that can be
532    * efficiently encoded with varint. (Otherwise, negative values must be sign-extended to 64 bits
533    * to be varint encoded, thus always taking 10 bytes on the wire.)
534    *
535    * @param n An unsigned 64-bit integer, stored in a signed int because Java has no explicit
536    *     unsigned support.
537    * @return A signed 64-bit integer.
538    */
539   public static long decodeZigZag64(final long n) {
540     return (n >>> 1) ^ -(n & 1);
541   }
542
543   /**
544    * Like {@link #readRawVarint32(InputStream)}, but expects that the caller has already read one
545    * byte. This allows the caller to determine if EOF has been reached before attempting to read.
546    */
547   public static int readRawVarint32(final int firstByte, final InputStream input)
548       throws IOException {
549     if ((firstByte & 0x80) == 0) {
550       return firstByte;
551     }
552
553     int result = firstByte & 0x7f;
554     int offset = 7;
555     for (; offset < 32; offset += 7) {
556       final int b = input.read();
557       if (b == -1) {
558         throw InvalidProtocolBufferException.truncatedMessage();
559       }
560       result |= (b & 0x7f) << offset;
561       if ((b & 0x80) == 0) {
562         return result;
563       }
564     }
565     // Keep reading up to 64 bits.
566     for (; offset < 64; offset += 7) {
567       final int b = input.read();
568       if (b == -1) {
569         throw InvalidProtocolBufferException.truncatedMessage();
570       }
571       if ((b & 0x80) == 0) {
572         return result;
573       }
574     }
575     throw InvalidProtocolBufferException.malformedVarint();
576   }
577
578   /**
579    * Reads a varint from the input one byte at a time, so that it does not read any bytes after the
580    * end of the varint. If you simply wrapped the stream in a CodedInputStream and used {@link
581    * #readRawVarint32(InputStream)} then you would probably end up reading past the end of the
582    * varint since CodedInputStream buffers its input.
583    */
584   static int readRawVarint32(final InputStream input) throws IOException {
585     final int firstByte = input.read();
586     if (firstByte == -1) {
587       throw InvalidProtocolBufferException.truncatedMessage();
588     }
589     return readRawVarint32(firstByte, input);
590   }
591
592   /** A {@link CodedInputStream} implementation that uses a backing array as the input. */
593   private static final class ArrayDecoder extends CodedInputStream {
594     private final byte[] buffer;
595     private final boolean immutable;
596     private int limit;
597     private int bufferSizeAfterLimit;
598     private int pos;
599     private int startPos;
600     private int lastTag;
601     private boolean enableAliasing;
602
603     /** The absolute position of the end of the current message. */
604     private int currentLimit = Integer.MAX_VALUE;
605
606     private ArrayDecoder(final byte[] buffer, final int offset, final int len, boolean immutable) {
607       this.buffer = buffer;
608       limit = offset + len;
609       pos = offset;
610       startPos = pos;
611       this.immutable = immutable;
612     }
613
614     @Override
615     public int readTag() throws IOException {
616       if (isAtEnd()) {
617         lastTag = 0;
618         return 0;
619       }
620
621       lastTag = readRawVarint32();
622       if (WireFormat.getTagFieldNumber(lastTag) == 0) {
623         // If we actually read zero (or any tag number corresponding to field
624         // number zero), that's not a valid tag.
625         throw InvalidProtocolBufferException.invalidTag();
626       }
627       return lastTag;
628     }
629
630     @Override
631     public void checkLastTagWas(final int value) throws InvalidProtocolBufferException {
632       if (lastTag != value) {
633         throw InvalidProtocolBufferException.invalidEndTag();
634       }
635     }
636
637     @Override
638     public int getLastTag() {
639       return lastTag;
640     }
641
642     @Override
643     public boolean skipField(final int tag) throws IOException {
644       switch (WireFormat.getTagWireType(tag)) {
645         case WireFormat.WIRETYPE_VARINT:
646           skipRawVarint();
647           return true;
648         case WireFormat.WIRETYPE_FIXED64:
649           skipRawBytes(FIXED64_SIZE);
650           return true;
651         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
652           skipRawBytes(readRawVarint32());
653           return true;
654         case WireFormat.WIRETYPE_START_GROUP:
655           skipMessage();
656           checkLastTagWas(
657               WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
658           return true;
659         case WireFormat.WIRETYPE_END_GROUP:
660           return false;
661         case WireFormat.WIRETYPE_FIXED32:
662           skipRawBytes(FIXED32_SIZE);
663           return true;
664         default:
665           throw InvalidProtocolBufferException.invalidWireType();
666       }
667     }
668
669     @Override
670     public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
671       switch (WireFormat.getTagWireType(tag)) {
672         case WireFormat.WIRETYPE_VARINT:
673           {
674             long value = readInt64();
675             output.writeRawVarint32(tag);
676             output.writeUInt64NoTag(value);
677             return true;
678           }
679         case WireFormat.WIRETYPE_FIXED64:
680           {
681             long value = readRawLittleEndian64();
682             output.writeRawVarint32(tag);
683             output.writeFixed64NoTag(value);
684             return true;
685           }
686         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
687           {
688             ByteString value = readBytes();
689             output.writeRawVarint32(tag);
690             output.writeBytesNoTag(value);
691             return true;
692           }
693         case WireFormat.WIRETYPE_START_GROUP:
694           {
695             output.writeRawVarint32(tag);
696             skipMessage(output);
697             int endtag =
698                 WireFormat.makeTag(
699                     WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
700             checkLastTagWas(endtag);
701             output.writeRawVarint32(endtag);
702             return true;
703           }
704         case WireFormat.WIRETYPE_END_GROUP:
705           {
706             return false;
707           }
708         case WireFormat.WIRETYPE_FIXED32:
709           {
710             int value = readRawLittleEndian32();
711             output.writeRawVarint32(tag);
712             output.writeFixed32NoTag(value);
713             return true;
714           }
715         default:
716           throw InvalidProtocolBufferException.invalidWireType();
717       }
718     }
719
720     @Override
721     public void skipMessage() throws IOException {
722       while (true) {
723         final int tag = readTag();
724         if (tag == 0 || !skipField(tag)) {
725           return;
726         }
727       }
728     }
729
730     @Override
731     public void skipMessage(CodedOutputStream output) throws IOException {
732       while (true) {
733         final int tag = readTag();
734         if (tag == 0 || !skipField(tag, output)) {
735           return;
736         }
737       }
738     }
739
740
741     // -----------------------------------------------------------------
742
743     @Override
744     public double readDouble() throws IOException {
745       return Double.longBitsToDouble(readRawLittleEndian64());
746     }
747
748     @Override
749     public float readFloat() throws IOException {
750       return Float.intBitsToFloat(readRawLittleEndian32());
751     }
752
753     @Override
754     public long readUInt64() throws IOException {
755       return readRawVarint64();
756     }
757
758     @Override
759     public long readInt64() throws IOException {
760       return readRawVarint64();
761     }
762
763     @Override
764     public int readInt32() throws IOException {
765       return readRawVarint32();
766     }
767
768     @Override
769     public long readFixed64() throws IOException {
770       return readRawLittleEndian64();
771     }
772
773     @Override
774     public int readFixed32() throws IOException {
775       return readRawLittleEndian32();
776     }
777
778     @Override
779     public boolean readBool() throws IOException {
780       return readRawVarint64() != 0;
781     }
782
783     @Override
784     public String readString() throws IOException {
785       final int size = readRawVarint32();
786       if (size > 0 && size <= (limit - pos)) {
787         // Fast path:  We already have the bytes in a contiguous buffer, so
788         //   just copy directly from it.
789         final String result = new String(buffer, pos, size, UTF_8);
790         pos += size;
791         return result;
792       }
793
794       if (size == 0) {
795         return "";
796       }
797       if (size < 0) {
798         throw InvalidProtocolBufferException.negativeSize();
799       }
800       throw InvalidProtocolBufferException.truncatedMessage();
801     }
802
803     @Override
804     public String readStringRequireUtf8() throws IOException {
805       final int size = readRawVarint32();
806       if (size > 0 && size <= (limit - pos)) {
807         String result = Utf8.decodeUtf8(buffer, pos, size);
808         pos += size;
809         return result;
810       }
811
812       if (size == 0) {
813         return "";
814       }
815       if (size <= 0) {
816         throw InvalidProtocolBufferException.negativeSize();
817       }
818       throw InvalidProtocolBufferException.truncatedMessage();
819     }
820
821     @Override
822     public void readGroup(
823         final int fieldNumber,
824         final MessageLite.Builder builder,
825         final ExtensionRegistryLite extensionRegistry)
826         throws IOException {
827       if (recursionDepth >= recursionLimit) {
828         throw InvalidProtocolBufferException.recursionLimitExceeded();
829       }
830       ++recursionDepth;
831       builder.mergeFrom(this, extensionRegistry);
832       checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
833       --recursionDepth;
834     }
835
836
837     @Override
838     public <T extends MessageLite> T readGroup(
839         final int fieldNumber,
840         final Parser<T> parser,
841         final ExtensionRegistryLite extensionRegistry)
842         throws IOException {
843       if (recursionDepth >= recursionLimit) {
844         throw InvalidProtocolBufferException.recursionLimitExceeded();
845       }
846       ++recursionDepth;
847       T result = parser.parsePartialFrom(this, extensionRegistry);
848       checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
849       --recursionDepth;
850       return result;
851     }
852
853     @Deprecated
854     @Override
855     public void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
856         throws IOException {
857       readGroup(fieldNumber, builder, ExtensionRegistryLite.getEmptyRegistry());
858     }
859
860     @Override
861     public void readMessage(
862         final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
863         throws IOException {
864       final int length = readRawVarint32();
865       if (recursionDepth >= recursionLimit) {
866         throw InvalidProtocolBufferException.recursionLimitExceeded();
867       }
868       final int oldLimit = pushLimit(length);
869       ++recursionDepth;
870       builder.mergeFrom(this, extensionRegistry);
871       checkLastTagWas(0);
872       --recursionDepth;
873       popLimit(oldLimit);
874     }
875
876
877     @Override
878     public <T extends MessageLite> T readMessage(
879         final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException {
880       int length = readRawVarint32();
881       if (recursionDepth >= recursionLimit) {
882         throw InvalidProtocolBufferException.recursionLimitExceeded();
883       }
884       final int oldLimit = pushLimit(length);
885       ++recursionDepth;
886       T result = parser.parsePartialFrom(this, extensionRegistry);
887       checkLastTagWas(0);
888       --recursionDepth;
889       popLimit(oldLimit);
890       return result;
891     }
892
893     @Override
894     public ByteString readBytes() throws IOException {
895       final int size = readRawVarint32();
896       if (size > 0 && size <= (limit - pos)) {
897         // Fast path:  We already have the bytes in a contiguous buffer, so
898         //   just copy directly from it.
899         final ByteString result =
900             immutable && enableAliasing
901                 ? ByteString.wrap(buffer, pos, size)
902                 : ByteString.copyFrom(buffer, pos, size);
903         pos += size;
904         return result;
905       }
906       if (size == 0) {
907         return ByteString.EMPTY;
908       }
909       // Slow path:  Build a byte array first then copy it.
910       return ByteString.wrap(readRawBytes(size));
911     }
912
913     @Override
914     public byte[] readByteArray() throws IOException {
915       final int size = readRawVarint32();
916       return readRawBytes(size);
917     }
918
919     @Override
920     public ByteBuffer readByteBuffer() throws IOException {
921       final int size = readRawVarint32();
922       if (size > 0 && size <= (limit - pos)) {
923         // Fast path: We already have the bytes in a contiguous buffer.
924         // When aliasing is enabled, we can return a ByteBuffer pointing directly
925         // into the underlying byte array without copy if the CodedInputStream is
926         // constructed from a byte array. If aliasing is disabled or the input is
927         // from an InputStream or ByteString, we have to make a copy of the bytes.
928         ByteBuffer result =
929             !immutable && enableAliasing
930                 ? ByteBuffer.wrap(buffer, pos, size).slice()
931                 : ByteBuffer.wrap(Arrays.copyOfRange(buffer, pos, pos + size));
932         pos += size;
933         // TODO(nathanmittler): Investigate making the ByteBuffer be made read-only
934         return result;
935       }
936
937       if (size == 0) {
938         return EMPTY_BYTE_BUFFER;
939       }
940       if (size < 0) {
941         throw InvalidProtocolBufferException.negativeSize();
942       }
943       throw InvalidProtocolBufferException.truncatedMessage();
944     }
945
946     @Override
947     public int readUInt32() throws IOException {
948       return readRawVarint32();
949     }
950
951     @Override
952     public int readEnum() throws IOException {
953       return readRawVarint32();
954     }
955
956     @Override
957     public int readSFixed32() throws IOException {
958       return readRawLittleEndian32();
959     }
960
961     @Override
962     public long readSFixed64() throws IOException {
963       return readRawLittleEndian64();
964     }
965
966     @Override
967     public int readSInt32() throws IOException {
968       return decodeZigZag32(readRawVarint32());
969     }
970
971     @Override
972     public long readSInt64() throws IOException {
973       return decodeZigZag64(readRawVarint64());
974     }
975
976     // =================================================================
977
978     @Override
979     public int readRawVarint32() throws IOException {
980       // See implementation notes for readRawVarint64
981       fastpath:
982       {
983         int tempPos = pos;
984
985         if (limit == tempPos) {
986           break fastpath;
987         }
988
989         final byte[] buffer = this.buffer;
990         int x;
991         if ((x = buffer[tempPos++]) >= 0) {
992           pos = tempPos;
993           return x;
994         } else if (limit - tempPos < 9) {
995           break fastpath;
996         } else if ((x ^= (buffer[tempPos++] << 7)) < 0) {
997           x ^= (~0 << 7);
998         } else if ((x ^= (buffer[tempPos++] << 14)) >= 0) {
999           x ^= (~0 << 7) ^ (~0 << 14);
1000         } else if ((x ^= (buffer[tempPos++] << 21)) < 0) {
1001           x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
1002         } else {
1003           int y = buffer[tempPos++];
1004           x ^= y << 28;
1005           x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
1006           if (y < 0
1007               && buffer[tempPos++] < 0
1008               && buffer[tempPos++] < 0
1009               && buffer[tempPos++] < 0
1010               && buffer[tempPos++] < 0
1011               && buffer[tempPos++] < 0) {
1012             break fastpath; // Will throw malformedVarint()
1013           }
1014         }
1015         pos = tempPos;
1016         return x;
1017       }
1018       return (int) readRawVarint64SlowPath();
1019     }
1020
1021     private void skipRawVarint() throws IOException {
1022       if (limit - pos >= MAX_VARINT_SIZE) {
1023         skipRawVarintFastPath();
1024       } else {
1025         skipRawVarintSlowPath();
1026       }
1027     }
1028
1029     private void skipRawVarintFastPath() throws IOException {
1030       for (int i = 0; i < MAX_VARINT_SIZE; i++) {
1031         if (buffer[pos++] >= 0) {
1032           return;
1033         }
1034       }
1035       throw InvalidProtocolBufferException.malformedVarint();
1036     }
1037
1038     private void skipRawVarintSlowPath() throws IOException {
1039       for (int i = 0; i < MAX_VARINT_SIZE; i++) {
1040         if (readRawByte() >= 0) {
1041           return;
1042         }
1043       }
1044       throw InvalidProtocolBufferException.malformedVarint();
1045     }
1046
1047     @Override
1048     public long readRawVarint64() throws IOException {
1049       // Implementation notes:
1050       //
1051       // Optimized for one-byte values, expected to be common.
1052       // The particular code below was selected from various candidates
1053       // empirically, by winning VarintBenchmark.
1054       //
1055       // Sign extension of (signed) Java bytes is usually a nuisance, but
1056       // we exploit it here to more easily obtain the sign of bytes read.
1057       // Instead of cleaning up the sign extension bits by masking eagerly,
1058       // we delay until we find the final (positive) byte, when we clear all
1059       // accumulated bits with one xor.  We depend on javac to constant fold.
1060       fastpath:
1061       {
1062         int tempPos = pos;
1063
1064         if (limit == tempPos) {
1065           break fastpath;
1066         }
1067
1068         final byte[] buffer = this.buffer;
1069         long x;
1070         int y;
1071         if ((y = buffer[tempPos++]) >= 0) {
1072           pos = tempPos;
1073           return y;
1074         } else if (limit - tempPos < 9) {
1075           break fastpath;
1076         } else if ((y ^= (buffer[tempPos++] << 7)) < 0) {
1077           x = y ^ (~0 << 7);
1078         } else if ((y ^= (buffer[tempPos++] << 14)) >= 0) {
1079           x = y ^ ((~0 << 7) ^ (~0 << 14));
1080         } else if ((y ^= (buffer[tempPos++] << 21)) < 0) {
1081           x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
1082         } else if ((x = y ^ ((long) buffer[tempPos++] << 28)) >= 0L) {
1083           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
1084         } else if ((x ^= ((long) buffer[tempPos++] << 35)) < 0L) {
1085           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
1086         } else if ((x ^= ((long) buffer[tempPos++] << 42)) >= 0L) {
1087           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
1088         } else if ((x ^= ((long) buffer[tempPos++] << 49)) < 0L) {
1089           x ^=
1090               (~0L << 7)
1091                   ^ (~0L << 14)
1092                   ^ (~0L << 21)
1093                   ^ (~0L << 28)
1094                   ^ (~0L << 35)
1095                   ^ (~0L << 42)
1096                   ^ (~0L << 49);
1097         } else {
1098           x ^= ((long) buffer[tempPos++] << 56);
1099           x ^=
1100               (~0L << 7)
1101                   ^ (~0L << 14)
1102                   ^ (~0L << 21)
1103                   ^ (~0L << 28)
1104                   ^ (~0L << 35)
1105                   ^ (~0L << 42)
1106                   ^ (~0L << 49)
1107                   ^ (~0L << 56);
1108           if (x < 0L) {
1109             if (buffer[tempPos++] < 0L) {
1110               break fastpath; // Will throw malformedVarint()
1111             }
1112           }
1113         }
1114         pos = tempPos;
1115         return x;
1116       }
1117       return readRawVarint64SlowPath();
1118     }
1119
1120     @Override
1121     long readRawVarint64SlowPath() throws IOException {
1122       long result = 0;
1123       for (int shift = 0; shift < 64; shift += 7) {
1124         final byte b = readRawByte();
1125         result |= (long) (b & 0x7F) << shift;
1126         if ((b & 0x80) == 0) {
1127           return result;
1128         }
1129       }
1130       throw InvalidProtocolBufferException.malformedVarint();
1131     }
1132
1133     @Override
1134     public int readRawLittleEndian32() throws IOException {
1135       int tempPos = pos;
1136
1137       if (limit - tempPos < FIXED32_SIZE) {
1138         throw InvalidProtocolBufferException.truncatedMessage();
1139       }
1140
1141       final byte[] buffer = this.buffer;
1142       pos = tempPos + FIXED32_SIZE;
1143       return (((buffer[tempPos] & 0xff))
1144           | ((buffer[tempPos + 1] & 0xff) << 8)
1145           | ((buffer[tempPos + 2] & 0xff) << 16)
1146           | ((buffer[tempPos + 3] & 0xff) << 24));
1147     }
1148
1149     @Override
1150     public long readRawLittleEndian64() throws IOException {
1151       int tempPos = pos;
1152
1153       if (limit - tempPos < FIXED64_SIZE) {
1154         throw InvalidProtocolBufferException.truncatedMessage();
1155       }
1156
1157       final byte[] buffer = this.buffer;
1158       pos = tempPos + FIXED64_SIZE;
1159       return (((buffer[tempPos] & 0xffL))
1160           | ((buffer[tempPos + 1] & 0xffL) << 8)
1161           | ((buffer[tempPos + 2] & 0xffL) << 16)
1162           | ((buffer[tempPos + 3] & 0xffL) << 24)
1163           | ((buffer[tempPos + 4] & 0xffL) << 32)
1164           | ((buffer[tempPos + 5] & 0xffL) << 40)
1165           | ((buffer[tempPos + 6] & 0xffL) << 48)
1166           | ((buffer[tempPos + 7] & 0xffL) << 56));
1167     }
1168
1169     @Override
1170     public void enableAliasing(boolean enabled) {
1171       this.enableAliasing = enabled;
1172     }
1173
1174     @Override
1175     public void resetSizeCounter() {
1176       startPos = pos;
1177     }
1178
1179     @Override
1180     public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
1181       if (byteLimit < 0) {
1182         throw InvalidProtocolBufferException.negativeSize();
1183       }
1184       byteLimit += getTotalBytesRead();
1185       final int oldLimit = currentLimit;
1186       if (byteLimit > oldLimit) {
1187         throw InvalidProtocolBufferException.truncatedMessage();
1188       }
1189       currentLimit = byteLimit;
1190
1191       recomputeBufferSizeAfterLimit();
1192
1193       return oldLimit;
1194     }
1195
1196     private void recomputeBufferSizeAfterLimit() {
1197       limit += bufferSizeAfterLimit;
1198       final int bufferEnd = limit - startPos;
1199       if (bufferEnd > currentLimit) {
1200         // Limit is in current buffer.
1201         bufferSizeAfterLimit = bufferEnd - currentLimit;
1202         limit -= bufferSizeAfterLimit;
1203       } else {
1204         bufferSizeAfterLimit = 0;
1205       }
1206     }
1207
1208     @Override
1209     public void popLimit(final int oldLimit) {
1210       currentLimit = oldLimit;
1211       recomputeBufferSizeAfterLimit();
1212     }
1213
1214     @Override
1215     public int getBytesUntilLimit() {
1216       if (currentLimit == Integer.MAX_VALUE) {
1217         return -1;
1218       }
1219
1220       return currentLimit - getTotalBytesRead();
1221     }
1222
1223     @Override
1224     public boolean isAtEnd() throws IOException {
1225       return pos == limit;
1226     }
1227
1228     @Override
1229     public int getTotalBytesRead() {
1230       return pos - startPos;
1231     }
1232
1233     @Override
1234     public byte readRawByte() throws IOException {
1235       if (pos == limit) {
1236         throw InvalidProtocolBufferException.truncatedMessage();
1237       }
1238       return buffer[pos++];
1239     }
1240
1241     @Override
1242     public byte[] readRawBytes(final int length) throws IOException {
1243       if (length > 0 && length <= (limit - pos)) {
1244         final int tempPos = pos;
1245         pos += length;
1246         return Arrays.copyOfRange(buffer, tempPos, pos);
1247       }
1248
1249       if (length <= 0) {
1250         if (length == 0) {
1251           return Internal.EMPTY_BYTE_ARRAY;
1252         } else {
1253           throw InvalidProtocolBufferException.negativeSize();
1254         }
1255       }
1256       throw InvalidProtocolBufferException.truncatedMessage();
1257     }
1258
1259     @Override
1260     public void skipRawBytes(final int length) throws IOException {
1261       if (length >= 0 && length <= (limit - pos)) {
1262         // We have all the bytes we need already.
1263         pos += length;
1264         return;
1265       }
1266
1267       if (length < 0) {
1268         throw InvalidProtocolBufferException.negativeSize();
1269       }
1270       throw InvalidProtocolBufferException.truncatedMessage();
1271     }
1272   }
1273
1274   /**
1275    * A {@link CodedInputStream} implementation that uses a backing direct ByteBuffer as the input.
1276    * Requires the use of {@code sun.misc.Unsafe} to perform fast reads on the buffer.
1277    */
1278   private static final class UnsafeDirectNioDecoder extends CodedInputStream {
1279     /** The direct buffer that is backing this stream. */
1280     private final ByteBuffer buffer;
1281
1282     /**
1283      * If {@code true}, indicates that the buffer is backing a {@link ByteString} and is therefore
1284      * considered to be an immutable input source.
1285      */
1286     private final boolean immutable;
1287
1288     /** The unsafe address of the content of {@link #buffer}. */
1289     private final long address;
1290
1291     /** The unsafe address of the current read limit of the buffer. */
1292     private long limit;
1293
1294     /** The unsafe address of the current read position of the buffer. */
1295     private long pos;
1296
1297     /** The unsafe address of the starting read position. */
1298     private long startPos;
1299
1300     /** The amount of available data in the buffer beyond {@link #limit}. */
1301     private int bufferSizeAfterLimit;
1302
1303     /** The last tag that was read from this stream. */
1304     private int lastTag;
1305
1306     /**
1307      * If {@code true}, indicates that calls to read {@link ByteString} or {@code byte[]}
1308      * <strong>may</strong> return slices of the underlying buffer, rather than copies.
1309      */
1310     private boolean enableAliasing;
1311
1312     /** The absolute position of the end of the current message. */
1313     private int currentLimit = Integer.MAX_VALUE;
1314
1315     static boolean isSupported() {
1316       return UnsafeUtil.hasUnsafeByteBufferOperations();
1317     }
1318
1319     private UnsafeDirectNioDecoder(ByteBuffer buffer, boolean immutable) {
1320       this.buffer = buffer;
1321       address = UnsafeUtil.addressOffset(buffer);
1322       limit = address + buffer.limit();
1323       pos = address + buffer.position();
1324       startPos = pos;
1325       this.immutable = immutable;
1326     }
1327
1328     @Override
1329     public int readTag() throws IOException {
1330       if (isAtEnd()) {
1331         lastTag = 0;
1332         return 0;
1333       }
1334
1335       lastTag = readRawVarint32();
1336       if (WireFormat.getTagFieldNumber(lastTag) == 0) {
1337         // If we actually read zero (or any tag number corresponding to field
1338         // number zero), that's not a valid tag.
1339         throw InvalidProtocolBufferException.invalidTag();
1340       }
1341       return lastTag;
1342     }
1343
1344     @Override
1345     public void checkLastTagWas(final int value) throws InvalidProtocolBufferException {
1346       if (lastTag != value) {
1347         throw InvalidProtocolBufferException.invalidEndTag();
1348       }
1349     }
1350
1351     @Override
1352     public int getLastTag() {
1353       return lastTag;
1354     }
1355
1356     @Override
1357     public boolean skipField(final int tag) throws IOException {
1358       switch (WireFormat.getTagWireType(tag)) {
1359         case WireFormat.WIRETYPE_VARINT:
1360           skipRawVarint();
1361           return true;
1362         case WireFormat.WIRETYPE_FIXED64:
1363           skipRawBytes(FIXED64_SIZE);
1364           return true;
1365         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
1366           skipRawBytes(readRawVarint32());
1367           return true;
1368         case WireFormat.WIRETYPE_START_GROUP:
1369           skipMessage();
1370           checkLastTagWas(
1371               WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
1372           return true;
1373         case WireFormat.WIRETYPE_END_GROUP:
1374           return false;
1375         case WireFormat.WIRETYPE_FIXED32:
1376           skipRawBytes(FIXED32_SIZE);
1377           return true;
1378         default:
1379           throw InvalidProtocolBufferException.invalidWireType();
1380       }
1381     }
1382
1383     @Override
1384     public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
1385       switch (WireFormat.getTagWireType(tag)) {
1386         case WireFormat.WIRETYPE_VARINT:
1387           {
1388             long value = readInt64();
1389             output.writeRawVarint32(tag);
1390             output.writeUInt64NoTag(value);
1391             return true;
1392           }
1393         case WireFormat.WIRETYPE_FIXED64:
1394           {
1395             long value = readRawLittleEndian64();
1396             output.writeRawVarint32(tag);
1397             output.writeFixed64NoTag(value);
1398             return true;
1399           }
1400         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
1401           {
1402             ByteString value = readBytes();
1403             output.writeRawVarint32(tag);
1404             output.writeBytesNoTag(value);
1405             return true;
1406           }
1407         case WireFormat.WIRETYPE_START_GROUP:
1408           {
1409             output.writeRawVarint32(tag);
1410             skipMessage(output);
1411             int endtag =
1412                 WireFormat.makeTag(
1413                     WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
1414             checkLastTagWas(endtag);
1415             output.writeRawVarint32(endtag);
1416             return true;
1417           }
1418         case WireFormat.WIRETYPE_END_GROUP:
1419           {
1420             return false;
1421           }
1422         case WireFormat.WIRETYPE_FIXED32:
1423           {
1424             int value = readRawLittleEndian32();
1425             output.writeRawVarint32(tag);
1426             output.writeFixed32NoTag(value);
1427             return true;
1428           }
1429         default:
1430           throw InvalidProtocolBufferException.invalidWireType();
1431       }
1432     }
1433
1434     @Override
1435     public void skipMessage() throws IOException {
1436       while (true) {
1437         final int tag = readTag();
1438         if (tag == 0 || !skipField(tag)) {
1439           return;
1440         }
1441       }
1442     }
1443
1444     @Override
1445     public void skipMessage(CodedOutputStream output) throws IOException {
1446       while (true) {
1447         final int tag = readTag();
1448         if (tag == 0 || !skipField(tag, output)) {
1449           return;
1450         }
1451       }
1452     }
1453
1454
1455     // -----------------------------------------------------------------
1456
1457     @Override
1458     public double readDouble() throws IOException {
1459       return Double.longBitsToDouble(readRawLittleEndian64());
1460     }
1461
1462     @Override
1463     public float readFloat() throws IOException {
1464       return Float.intBitsToFloat(readRawLittleEndian32());
1465     }
1466
1467     @Override
1468     public long readUInt64() throws IOException {
1469       return readRawVarint64();
1470     }
1471
1472     @Override
1473     public long readInt64() throws IOException {
1474       return readRawVarint64();
1475     }
1476
1477     @Override
1478     public int readInt32() throws IOException {
1479       return readRawVarint32();
1480     }
1481
1482     @Override
1483     public long readFixed64() throws IOException {
1484       return readRawLittleEndian64();
1485     }
1486
1487     @Override
1488     public int readFixed32() throws IOException {
1489       return readRawLittleEndian32();
1490     }
1491
1492     @Override
1493     public boolean readBool() throws IOException {
1494       return readRawVarint64() != 0;
1495     }
1496
1497     @Override
1498     public String readString() throws IOException {
1499       final int size = readRawVarint32();
1500       if (size > 0 && size <= remaining()) {
1501         // TODO(nathanmittler): Is there a way to avoid this copy?
1502         // TODO(anuraaga): It might be possible to share the optimized loop with
1503         // readStringRequireUtf8 by implementing Java replacement logic there.
1504         // The same as readBytes' logic
1505         byte[] bytes = new byte[size];
1506         UnsafeUtil.copyMemory(pos, bytes, 0, size);
1507         String result = new String(bytes, UTF_8);
1508         pos += size;
1509         return result;
1510       }
1511
1512       if (size == 0) {
1513         return "";
1514       }
1515       if (size < 0) {
1516         throw InvalidProtocolBufferException.negativeSize();
1517       }
1518       throw InvalidProtocolBufferException.truncatedMessage();
1519     }
1520
1521     @Override
1522     public String readStringRequireUtf8() throws IOException {
1523       final int size = readRawVarint32();
1524       if (size > 0 && size <= remaining()) {
1525         final int bufferPos = bufferPos(pos);
1526         String result = Utf8.decodeUtf8(buffer, bufferPos, size);
1527         pos += size;
1528         return result;
1529       }
1530
1531       if (size == 0) {
1532         return "";
1533       }
1534       if (size <= 0) {
1535         throw InvalidProtocolBufferException.negativeSize();
1536       }
1537       throw InvalidProtocolBufferException.truncatedMessage();
1538     }
1539
1540     @Override
1541     public void readGroup(
1542         final int fieldNumber,
1543         final MessageLite.Builder builder,
1544         final ExtensionRegistryLite extensionRegistry)
1545         throws IOException {
1546       if (recursionDepth >= recursionLimit) {
1547         throw InvalidProtocolBufferException.recursionLimitExceeded();
1548       }
1549       ++recursionDepth;
1550       builder.mergeFrom(this, extensionRegistry);
1551       checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
1552       --recursionDepth;
1553     }
1554
1555
1556     @Override
1557     public <T extends MessageLite> T readGroup(
1558         final int fieldNumber,
1559         final Parser<T> parser,
1560         final ExtensionRegistryLite extensionRegistry)
1561         throws IOException {
1562       if (recursionDepth >= recursionLimit) {
1563         throw InvalidProtocolBufferException.recursionLimitExceeded();
1564       }
1565       ++recursionDepth;
1566       T result = parser.parsePartialFrom(this, extensionRegistry);
1567       checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
1568       --recursionDepth;
1569       return result;
1570     }
1571
1572     @Deprecated
1573     @Override
1574     public void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
1575         throws IOException {
1576       readGroup(fieldNumber, builder, ExtensionRegistryLite.getEmptyRegistry());
1577     }
1578
1579     @Override
1580     public void readMessage(
1581         final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
1582         throws IOException {
1583       final int length = readRawVarint32();
1584       if (recursionDepth >= recursionLimit) {
1585         throw InvalidProtocolBufferException.recursionLimitExceeded();
1586       }
1587       final int oldLimit = pushLimit(length);
1588       ++recursionDepth;
1589       builder.mergeFrom(this, extensionRegistry);
1590       checkLastTagWas(0);
1591       --recursionDepth;
1592       popLimit(oldLimit);
1593     }
1594
1595
1596     @Override
1597     public <T extends MessageLite> T readMessage(
1598         final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException {
1599       int length = readRawVarint32();
1600       if (recursionDepth >= recursionLimit) {
1601         throw InvalidProtocolBufferException.recursionLimitExceeded();
1602       }
1603       final int oldLimit = pushLimit(length);
1604       ++recursionDepth;
1605       T result = parser.parsePartialFrom(this, extensionRegistry);
1606       checkLastTagWas(0);
1607       --recursionDepth;
1608       popLimit(oldLimit);
1609       return result;
1610     }
1611
1612     @Override
1613     public ByteString readBytes() throws IOException {
1614       final int size = readRawVarint32();
1615       if (size > 0 && size <= remaining()) {
1616         if (immutable && enableAliasing) {
1617           final ByteBuffer result = slice(pos, pos + size);
1618           pos += size;
1619           return ByteString.wrap(result);
1620         } else {
1621           // Use UnsafeUtil to copy the memory to bytes instead of using ByteBuffer ways.
1622           byte[] bytes = new byte[size];
1623           UnsafeUtil.copyMemory(pos, bytes, 0, size);
1624           pos += size;
1625           return ByteString.wrap(bytes);
1626         }
1627       }
1628
1629       if (size == 0) {
1630         return ByteString.EMPTY;
1631       }
1632       if (size < 0) {
1633         throw InvalidProtocolBufferException.negativeSize();
1634       }
1635       throw InvalidProtocolBufferException.truncatedMessage();
1636     }
1637
1638     @Override
1639     public byte[] readByteArray() throws IOException {
1640       return readRawBytes(readRawVarint32());
1641     }
1642
1643     @Override
1644     public ByteBuffer readByteBuffer() throws IOException {
1645       final int size = readRawVarint32();
1646       if (size > 0 && size <= remaining()) {
1647         // "Immutable" implies that buffer is backing a ByteString.
1648         // Disallow slicing in this case to prevent the caller from modifying the contents
1649         // of the ByteString.
1650         if (!immutable && enableAliasing) {
1651           final ByteBuffer result = slice(pos, pos + size);
1652           pos += size;
1653           return result;
1654         } else {
1655           // The same as readBytes' logic
1656           byte[] bytes = new byte[size];
1657           UnsafeUtil.copyMemory(pos, bytes, 0, size);
1658           pos += size;
1659           return ByteBuffer.wrap(bytes);
1660         }
1661         // TODO(nathanmittler): Investigate making the ByteBuffer be made read-only
1662       }
1663
1664       if (size == 0) {
1665         return EMPTY_BYTE_BUFFER;
1666       }
1667       if (size < 0) {
1668         throw InvalidProtocolBufferException.negativeSize();
1669       }
1670       throw InvalidProtocolBufferException.truncatedMessage();
1671     }
1672
1673     @Override
1674     public int readUInt32() throws IOException {
1675       return readRawVarint32();
1676     }
1677
1678     @Override
1679     public int readEnum() throws IOException {
1680       return readRawVarint32();
1681     }
1682
1683     @Override
1684     public int readSFixed32() throws IOException {
1685       return readRawLittleEndian32();
1686     }
1687
1688     @Override
1689     public long readSFixed64() throws IOException {
1690       return readRawLittleEndian64();
1691     }
1692
1693     @Override
1694     public int readSInt32() throws IOException {
1695       return decodeZigZag32(readRawVarint32());
1696     }
1697
1698     @Override
1699     public long readSInt64() throws IOException {
1700       return decodeZigZag64(readRawVarint64());
1701     }
1702
1703     // =================================================================
1704
1705     @Override
1706     public int readRawVarint32() throws IOException {
1707       // See implementation notes for readRawVarint64
1708       fastpath:
1709       {
1710         long tempPos = pos;
1711
1712         if (limit == tempPos) {
1713           break fastpath;
1714         }
1715
1716         int x;
1717         if ((x = UnsafeUtil.getByte(tempPos++)) >= 0) {
1718           pos = tempPos;
1719           return x;
1720         } else if (limit - tempPos < 9) {
1721           break fastpath;
1722         } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 7)) < 0) {
1723           x ^= (~0 << 7);
1724         } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 14)) >= 0) {
1725           x ^= (~0 << 7) ^ (~0 << 14);
1726         } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 21)) < 0) {
1727           x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
1728         } else {
1729           int y = UnsafeUtil.getByte(tempPos++);
1730           x ^= y << 28;
1731           x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
1732           if (y < 0
1733               && UnsafeUtil.getByte(tempPos++) < 0
1734               && UnsafeUtil.getByte(tempPos++) < 0
1735               && UnsafeUtil.getByte(tempPos++) < 0
1736               && UnsafeUtil.getByte(tempPos++) < 0
1737               && UnsafeUtil.getByte(tempPos++) < 0) {
1738             break fastpath; // Will throw malformedVarint()
1739           }
1740         }
1741         pos = tempPos;
1742         return x;
1743       }
1744       return (int) readRawVarint64SlowPath();
1745     }
1746
1747     private void skipRawVarint() throws IOException {
1748       if (remaining() >= MAX_VARINT_SIZE) {
1749         skipRawVarintFastPath();
1750       } else {
1751         skipRawVarintSlowPath();
1752       }
1753     }
1754
1755     private void skipRawVarintFastPath() throws IOException {
1756       for (int i = 0; i < MAX_VARINT_SIZE; i++) {
1757         if (UnsafeUtil.getByte(pos++) >= 0) {
1758           return;
1759         }
1760       }
1761       throw InvalidProtocolBufferException.malformedVarint();
1762     }
1763
1764     private void skipRawVarintSlowPath() throws IOException {
1765       for (int i = 0; i < MAX_VARINT_SIZE; i++) {
1766         if (readRawByte() >= 0) {
1767           return;
1768         }
1769       }
1770       throw InvalidProtocolBufferException.malformedVarint();
1771     }
1772
1773     @Override
1774     public long readRawVarint64() throws IOException {
1775       // Implementation notes:
1776       //
1777       // Optimized for one-byte values, expected to be common.
1778       // The particular code below was selected from various candidates
1779       // empirically, by winning VarintBenchmark.
1780       //
1781       // Sign extension of (signed) Java bytes is usually a nuisance, but
1782       // we exploit it here to more easily obtain the sign of bytes read.
1783       // Instead of cleaning up the sign extension bits by masking eagerly,
1784       // we delay until we find the final (positive) byte, when we clear all
1785       // accumulated bits with one xor.  We depend on javac to constant fold.
1786       fastpath:
1787       {
1788         long tempPos = pos;
1789
1790         if (limit == tempPos) {
1791           break fastpath;
1792         }
1793
1794         long x;
1795         int y;
1796         if ((y = UnsafeUtil.getByte(tempPos++)) >= 0) {
1797           pos = tempPos;
1798           return y;
1799         } else if (limit - tempPos < 9) {
1800           break fastpath;
1801         } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 7)) < 0) {
1802           x = y ^ (~0 << 7);
1803         } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 14)) >= 0) {
1804           x = y ^ ((~0 << 7) ^ (~0 << 14));
1805         } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 21)) < 0) {
1806           x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
1807         } else if ((x = y ^ ((long) UnsafeUtil.getByte(tempPos++) << 28)) >= 0L) {
1808           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
1809         } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 35)) < 0L) {
1810           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
1811         } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 42)) >= 0L) {
1812           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
1813         } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 49)) < 0L) {
1814           x ^=
1815               (~0L << 7)
1816                   ^ (~0L << 14)
1817                   ^ (~0L << 21)
1818                   ^ (~0L << 28)
1819                   ^ (~0L << 35)
1820                   ^ (~0L << 42)
1821                   ^ (~0L << 49);
1822         } else {
1823           x ^= ((long) UnsafeUtil.getByte(tempPos++) << 56);
1824           x ^=
1825               (~0L << 7)
1826                   ^ (~0L << 14)
1827                   ^ (~0L << 21)
1828                   ^ (~0L << 28)
1829                   ^ (~0L << 35)
1830                   ^ (~0L << 42)
1831                   ^ (~0L << 49)
1832                   ^ (~0L << 56);
1833           if (x < 0L) {
1834             if (UnsafeUtil.getByte(tempPos++) < 0L) {
1835               break fastpath; // Will throw malformedVarint()
1836             }
1837           }
1838         }
1839         pos = tempPos;
1840         return x;
1841       }
1842       return readRawVarint64SlowPath();
1843     }
1844
1845     @Override
1846     long readRawVarint64SlowPath() throws IOException {
1847       long result = 0;
1848       for (int shift = 0; shift < 64; shift += 7) {
1849         final byte b = readRawByte();
1850         result |= (long) (b & 0x7F) << shift;
1851         if ((b & 0x80) == 0) {
1852           return result;
1853         }
1854       }
1855       throw InvalidProtocolBufferException.malformedVarint();
1856     }
1857
1858     @Override
1859     public int readRawLittleEndian32() throws IOException {
1860       long tempPos = pos;
1861
1862       if (limit - tempPos < FIXED32_SIZE) {
1863         throw InvalidProtocolBufferException.truncatedMessage();
1864       }
1865
1866       pos = tempPos + FIXED32_SIZE;
1867       return (((UnsafeUtil.getByte(tempPos) & 0xff))
1868           | ((UnsafeUtil.getByte(tempPos + 1) & 0xff) << 8)
1869           | ((UnsafeUtil.getByte(tempPos + 2) & 0xff) << 16)
1870           | ((UnsafeUtil.getByte(tempPos + 3) & 0xff) << 24));
1871     }
1872
1873     @Override
1874     public long readRawLittleEndian64() throws IOException {
1875       long tempPos = pos;
1876
1877       if (limit - tempPos < FIXED64_SIZE) {
1878         throw InvalidProtocolBufferException.truncatedMessage();
1879       }
1880
1881       pos = tempPos + FIXED64_SIZE;
1882       return (((UnsafeUtil.getByte(tempPos) & 0xffL))
1883           | ((UnsafeUtil.getByte(tempPos + 1) & 0xffL) << 8)
1884           | ((UnsafeUtil.getByte(tempPos + 2) & 0xffL) << 16)
1885           | ((UnsafeUtil.getByte(tempPos + 3) & 0xffL) << 24)
1886           | ((UnsafeUtil.getByte(tempPos + 4) & 0xffL) << 32)
1887           | ((UnsafeUtil.getByte(tempPos + 5) & 0xffL) << 40)
1888           | ((UnsafeUtil.getByte(tempPos + 6) & 0xffL) << 48)
1889           | ((UnsafeUtil.getByte(tempPos + 7) & 0xffL) << 56));
1890     }
1891
1892     @Override
1893     public void enableAliasing(boolean enabled) {
1894       this.enableAliasing = enabled;
1895     }
1896
1897     @Override
1898     public void resetSizeCounter() {
1899       startPos = pos;
1900     }
1901
1902     @Override
1903     public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
1904       if (byteLimit < 0) {
1905         throw InvalidProtocolBufferException.negativeSize();
1906       }
1907       byteLimit += getTotalBytesRead();
1908       final int oldLimit = currentLimit;
1909       if (byteLimit > oldLimit) {
1910         throw InvalidProtocolBufferException.truncatedMessage();
1911       }
1912       currentLimit = byteLimit;
1913
1914       recomputeBufferSizeAfterLimit();
1915
1916       return oldLimit;
1917     }
1918
1919     @Override
1920     public void popLimit(final int oldLimit) {
1921       currentLimit = oldLimit;
1922       recomputeBufferSizeAfterLimit();
1923     }
1924
1925     @Override
1926     public int getBytesUntilLimit() {
1927       if (currentLimit == Integer.MAX_VALUE) {
1928         return -1;
1929       }
1930
1931       return currentLimit - getTotalBytesRead();
1932     }
1933
1934     @Override
1935     public boolean isAtEnd() throws IOException {
1936       return pos == limit;
1937     }
1938
1939     @Override
1940     public int getTotalBytesRead() {
1941       return (int) (pos - startPos);
1942     }
1943
1944     @Override
1945     public byte readRawByte() throws IOException {
1946       if (pos == limit) {
1947         throw InvalidProtocolBufferException.truncatedMessage();
1948       }
1949       return UnsafeUtil.getByte(pos++);
1950     }
1951
1952     @Override
1953     public byte[] readRawBytes(final int length) throws IOException {
1954       if (length >= 0 && length <= remaining()) {
1955         byte[] bytes = new byte[length];
1956         slice(pos, pos + length).get(bytes);
1957         pos += length;
1958         return bytes;
1959       }
1960
1961       if (length <= 0) {
1962         if (length == 0) {
1963           return EMPTY_BYTE_ARRAY;
1964         } else {
1965           throw InvalidProtocolBufferException.negativeSize();
1966         }
1967       }
1968
1969       throw InvalidProtocolBufferException.truncatedMessage();
1970     }
1971
1972     @Override
1973     public void skipRawBytes(final int length) throws IOException {
1974       if (length >= 0 && length <= remaining()) {
1975         // We have all the bytes we need already.
1976         pos += length;
1977         return;
1978       }
1979
1980       if (length < 0) {
1981         throw InvalidProtocolBufferException.negativeSize();
1982       }
1983       throw InvalidProtocolBufferException.truncatedMessage();
1984     }
1985
1986     private void recomputeBufferSizeAfterLimit() {
1987       limit += bufferSizeAfterLimit;
1988       final int bufferEnd = (int) (limit - startPos);
1989       if (bufferEnd > currentLimit) {
1990         // Limit is in current buffer.
1991         bufferSizeAfterLimit = bufferEnd - currentLimit;
1992         limit -= bufferSizeAfterLimit;
1993       } else {
1994         bufferSizeAfterLimit = 0;
1995       }
1996     }
1997
1998     private int remaining() {
1999       return (int) (limit - pos);
2000     }
2001
2002     private int bufferPos(long pos) {
2003       return (int) (pos - address);
2004     }
2005
2006     private ByteBuffer slice(long begin, long end) throws IOException {
2007       int prevPos = buffer.position();
2008       int prevLimit = buffer.limit();
2009       try {
2010         buffer.position(bufferPos(begin));
2011         buffer.limit(bufferPos(end));
2012         return buffer.slice();
2013       } catch (IllegalArgumentException e) {
2014         throw InvalidProtocolBufferException.truncatedMessage();
2015       } finally {
2016         buffer.position(prevPos);
2017         buffer.limit(prevLimit);
2018       }
2019     }
2020   }
2021
2022   /**
2023    * Implementation of {@link CodedInputStream} that uses an {@link InputStream} as the data source.
2024    */
2025   private static final class StreamDecoder extends CodedInputStream {
2026     private final InputStream input;
2027     private final byte[] buffer;
2028     /** bufferSize represents how many bytes are currently filled in the buffer */
2029     private int bufferSize;
2030
2031     private int bufferSizeAfterLimit;
2032     private int pos;
2033     private int lastTag;
2034
2035     /**
2036      * The total number of bytes read before the current buffer. The total bytes read up to the
2037      * current position can be computed as {@code totalBytesRetired + pos}. This value may be
2038      * negative if reading started in the middle of the current buffer (e.g. if the constructor that
2039      * takes a byte array and an offset was used).
2040      */
2041     private int totalBytesRetired;
2042
2043     /** The absolute position of the end of the current message. */
2044     private int currentLimit = Integer.MAX_VALUE;
2045
2046     private StreamDecoder(final InputStream input, int bufferSize) {
2047       checkNotNull(input, "input");
2048       this.input = input;
2049       this.buffer = new byte[bufferSize];
2050       this.bufferSize = 0;
2051       pos = 0;
2052       totalBytesRetired = 0;
2053     }
2054
2055     @Override
2056     public int readTag() throws IOException {
2057       if (isAtEnd()) {
2058         lastTag = 0;
2059         return 0;
2060       }
2061
2062       lastTag = readRawVarint32();
2063       if (WireFormat.getTagFieldNumber(lastTag) == 0) {
2064         // If we actually read zero (or any tag number corresponding to field
2065         // number zero), that's not a valid tag.
2066         throw InvalidProtocolBufferException.invalidTag();
2067       }
2068       return lastTag;
2069     }
2070
2071     @Override
2072     public void checkLastTagWas(final int value) throws InvalidProtocolBufferException {
2073       if (lastTag != value) {
2074         throw InvalidProtocolBufferException.invalidEndTag();
2075       }
2076     }
2077
2078     @Override
2079     public int getLastTag() {
2080       return lastTag;
2081     }
2082
2083     @Override
2084     public boolean skipField(final int tag) throws IOException {
2085       switch (WireFormat.getTagWireType(tag)) {
2086         case WireFormat.WIRETYPE_VARINT:
2087           skipRawVarint();
2088           return true;
2089         case WireFormat.WIRETYPE_FIXED64:
2090           skipRawBytes(FIXED64_SIZE);
2091           return true;
2092         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
2093           skipRawBytes(readRawVarint32());
2094           return true;
2095         case WireFormat.WIRETYPE_START_GROUP:
2096           skipMessage();
2097           checkLastTagWas(
2098               WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
2099           return true;
2100         case WireFormat.WIRETYPE_END_GROUP:
2101           return false;
2102         case WireFormat.WIRETYPE_FIXED32:
2103           skipRawBytes(FIXED32_SIZE);
2104           return true;
2105         default:
2106           throw InvalidProtocolBufferException.invalidWireType();
2107       }
2108     }
2109
2110     @Override
2111     public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
2112       switch (WireFormat.getTagWireType(tag)) {
2113         case WireFormat.WIRETYPE_VARINT:
2114           {
2115             long value = readInt64();
2116             output.writeRawVarint32(tag);
2117             output.writeUInt64NoTag(value);
2118             return true;
2119           }
2120         case WireFormat.WIRETYPE_FIXED64:
2121           {
2122             long value = readRawLittleEndian64();
2123             output.writeRawVarint32(tag);
2124             output.writeFixed64NoTag(value);
2125             return true;
2126           }
2127         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
2128           {
2129             ByteString value = readBytes();
2130             output.writeRawVarint32(tag);
2131             output.writeBytesNoTag(value);
2132             return true;
2133           }
2134         case WireFormat.WIRETYPE_START_GROUP:
2135           {
2136             output.writeRawVarint32(tag);
2137             skipMessage(output);
2138             int endtag =
2139                 WireFormat.makeTag(
2140                     WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
2141             checkLastTagWas(endtag);
2142             output.writeRawVarint32(endtag);
2143             return true;
2144           }
2145         case WireFormat.WIRETYPE_END_GROUP:
2146           {
2147             return false;
2148           }
2149         case WireFormat.WIRETYPE_FIXED32:
2150           {
2151             int value = readRawLittleEndian32();
2152             output.writeRawVarint32(tag);
2153             output.writeFixed32NoTag(value);
2154             return true;
2155           }
2156         default:
2157           throw InvalidProtocolBufferException.invalidWireType();
2158       }
2159     }
2160
2161     @Override
2162     public void skipMessage() throws IOException {
2163       while (true) {
2164         final int tag = readTag();
2165         if (tag == 0 || !skipField(tag)) {
2166           return;
2167         }
2168       }
2169     }
2170
2171     @Override
2172     public void skipMessage(CodedOutputStream output) throws IOException {
2173       while (true) {
2174         final int tag = readTag();
2175         if (tag == 0 || !skipField(tag, output)) {
2176           return;
2177         }
2178       }
2179     }
2180
2181     /** Collects the bytes skipped and returns the data in a ByteBuffer. */
2182     private class SkippedDataSink implements RefillCallback {
2183       private int lastPos = pos;
2184       private ByteArrayOutputStream byteArrayStream;
2185
2186       @Override
2187       public void onRefill() {
2188         if (byteArrayStream == null) {
2189           byteArrayStream = new ByteArrayOutputStream();
2190         }
2191         byteArrayStream.write(buffer, lastPos, pos - lastPos);
2192         lastPos = 0;
2193       }
2194
2195       /** Gets skipped data in a ByteBuffer. This method should only be called once. */
2196       ByteBuffer getSkippedData() {
2197         if (byteArrayStream == null) {
2198           return ByteBuffer.wrap(buffer, lastPos, pos - lastPos);
2199         } else {
2200           byteArrayStream.write(buffer, lastPos, pos);
2201           return ByteBuffer.wrap(byteArrayStream.toByteArray());
2202         }
2203       }
2204     }
2205
2206
2207     // -----------------------------------------------------------------
2208
2209     @Override
2210     public double readDouble() throws IOException {
2211       return Double.longBitsToDouble(readRawLittleEndian64());
2212     }
2213
2214     @Override
2215     public float readFloat() throws IOException {
2216       return Float.intBitsToFloat(readRawLittleEndian32());
2217     }
2218
2219     @Override
2220     public long readUInt64() throws IOException {
2221       return readRawVarint64();
2222     }
2223
2224     @Override
2225     public long readInt64() throws IOException {
2226       return readRawVarint64();
2227     }
2228
2229     @Override
2230     public int readInt32() throws IOException {
2231       return readRawVarint32();
2232     }
2233
2234     @Override
2235     public long readFixed64() throws IOException {
2236       return readRawLittleEndian64();
2237     }
2238
2239     @Override
2240     public int readFixed32() throws IOException {
2241       return readRawLittleEndian32();
2242     }
2243
2244     @Override
2245     public boolean readBool() throws IOException {
2246       return readRawVarint64() != 0;
2247     }
2248
2249     @Override
2250     public String readString() throws IOException {
2251       final int size = readRawVarint32();
2252       if (size > 0 && size <= (bufferSize - pos)) {
2253         // Fast path:  We already have the bytes in a contiguous buffer, so
2254         //   just copy directly from it.
2255         final String result = new String(buffer, pos, size, UTF_8);
2256         pos += size;
2257         return result;
2258       }
2259       if (size == 0) {
2260         return "";
2261       }
2262       if (size <= bufferSize) {
2263         refillBuffer(size);
2264         String result = new String(buffer, pos, size, UTF_8);
2265         pos += size;
2266         return result;
2267       }
2268       // Slow path:  Build a byte array first then copy it.
2269       return new String(readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ false), UTF_8);
2270     }
2271
2272     @Override
2273     public String readStringRequireUtf8() throws IOException {
2274       final int size = readRawVarint32();
2275       final byte[] bytes;
2276       final int oldPos = pos;
2277       final int tempPos;
2278       if (size <= (bufferSize - oldPos) && size > 0) {
2279         // Fast path:  We already have the bytes in a contiguous buffer, so
2280         //   just copy directly from it.
2281         bytes = buffer;
2282         pos = oldPos + size;
2283         tempPos = oldPos;
2284       } else if (size == 0) {
2285         return "";
2286       } else if (size <= bufferSize) {
2287         refillBuffer(size);
2288         bytes = buffer;
2289         tempPos = 0;
2290         pos = tempPos + size;
2291       } else {
2292         // Slow path:  Build a byte array first then copy it.
2293         bytes = readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ false);
2294         tempPos = 0;
2295       }
2296       return Utf8.decodeUtf8(bytes, tempPos, size);
2297     }
2298
2299     @Override
2300     public void readGroup(
2301         final int fieldNumber,
2302         final MessageLite.Builder builder,
2303         final ExtensionRegistryLite extensionRegistry)
2304         throws IOException {
2305       if (recursionDepth >= recursionLimit) {
2306         throw InvalidProtocolBufferException.recursionLimitExceeded();
2307       }
2308       ++recursionDepth;
2309       builder.mergeFrom(this, extensionRegistry);
2310       checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
2311       --recursionDepth;
2312     }
2313
2314
2315     @Override
2316     public <T extends MessageLite> T readGroup(
2317         final int fieldNumber,
2318         final Parser<T> parser,
2319         final ExtensionRegistryLite extensionRegistry)
2320         throws IOException {
2321       if (recursionDepth >= recursionLimit) {
2322         throw InvalidProtocolBufferException.recursionLimitExceeded();
2323       }
2324       ++recursionDepth;
2325       T result = parser.parsePartialFrom(this, extensionRegistry);
2326       checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
2327       --recursionDepth;
2328       return result;
2329     }
2330
2331     @Deprecated
2332     @Override
2333     public void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
2334         throws IOException {
2335       readGroup(fieldNumber, builder, ExtensionRegistryLite.getEmptyRegistry());
2336     }
2337
2338     @Override
2339     public void readMessage(
2340         final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
2341         throws IOException {
2342       final int length = readRawVarint32();
2343       if (recursionDepth >= recursionLimit) {
2344         throw InvalidProtocolBufferException.recursionLimitExceeded();
2345       }
2346       final int oldLimit = pushLimit(length);
2347       ++recursionDepth;
2348       builder.mergeFrom(this, extensionRegistry);
2349       checkLastTagWas(0);
2350       --recursionDepth;
2351       popLimit(oldLimit);
2352     }
2353
2354
2355     @Override
2356     public <T extends MessageLite> T readMessage(
2357         final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException {
2358       int length = readRawVarint32();
2359       if (recursionDepth >= recursionLimit) {
2360         throw InvalidProtocolBufferException.recursionLimitExceeded();
2361       }
2362       final int oldLimit = pushLimit(length);
2363       ++recursionDepth;
2364       T result = parser.parsePartialFrom(this, extensionRegistry);
2365       checkLastTagWas(0);
2366       --recursionDepth;
2367       popLimit(oldLimit);
2368       return result;
2369     }
2370
2371     @Override
2372     public ByteString readBytes() throws IOException {
2373       final int size = readRawVarint32();
2374       if (size <= (bufferSize - pos) && size > 0) {
2375         // Fast path:  We already have the bytes in a contiguous buffer, so
2376         //   just copy directly from it.
2377         final ByteString result = ByteString.copyFrom(buffer, pos, size);
2378         pos += size;
2379         return result;
2380       }
2381       if (size == 0) {
2382         return ByteString.EMPTY;
2383       }
2384       return readBytesSlowPath(size);
2385     }
2386
2387     @Override
2388     public byte[] readByteArray() throws IOException {
2389       final int size = readRawVarint32();
2390       if (size <= (bufferSize - pos) && size > 0) {
2391         // Fast path: We already have the bytes in a contiguous buffer, so
2392         // just copy directly from it.
2393         final byte[] result = Arrays.copyOfRange(buffer, pos, pos + size);
2394         pos += size;
2395         return result;
2396       } else {
2397         // Slow path: Build a byte array first then copy it.
2398         // TODO(dweis): Do we want to protect from malicious input streams here?
2399         return readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ false);
2400       }
2401     }
2402
2403     @Override
2404     public ByteBuffer readByteBuffer() throws IOException {
2405       final int size = readRawVarint32();
2406       if (size <= (bufferSize - pos) && size > 0) {
2407         // Fast path: We already have the bytes in a contiguous buffer.
2408         ByteBuffer result = ByteBuffer.wrap(Arrays.copyOfRange(buffer, pos, pos + size));
2409         pos += size;
2410         return result;
2411       }
2412       if (size == 0) {
2413         return Internal.EMPTY_BYTE_BUFFER;
2414       }
2415       // Slow path: Build a byte array first then copy it.
2416       
2417       // We must copy as the byte array was handed off to the InputStream and a malicious
2418       // implementation could retain a reference.
2419       return ByteBuffer.wrap(readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ true));
2420     }
2421
2422     @Override
2423     public int readUInt32() throws IOException {
2424       return readRawVarint32();
2425     }
2426
2427     @Override
2428     public int readEnum() throws IOException {
2429       return readRawVarint32();
2430     }
2431
2432     @Override
2433     public int readSFixed32() throws IOException {
2434       return readRawLittleEndian32();
2435     }
2436
2437     @Override
2438     public long readSFixed64() throws IOException {
2439       return readRawLittleEndian64();
2440     }
2441
2442     @Override
2443     public int readSInt32() throws IOException {
2444       return decodeZigZag32(readRawVarint32());
2445     }
2446
2447     @Override
2448     public long readSInt64() throws IOException {
2449       return decodeZigZag64(readRawVarint64());
2450     }
2451
2452     // =================================================================
2453
2454     @Override
2455     public int readRawVarint32() throws IOException {
2456       // See implementation notes for readRawVarint64
2457       fastpath:
2458       {
2459         int tempPos = pos;
2460
2461         if (bufferSize == tempPos) {
2462           break fastpath;
2463         }
2464
2465         final byte[] buffer = this.buffer;
2466         int x;
2467         if ((x = buffer[tempPos++]) >= 0) {
2468           pos = tempPos;
2469           return x;
2470         } else if (bufferSize - tempPos < 9) {
2471           break fastpath;
2472         } else if ((x ^= (buffer[tempPos++] << 7)) < 0) {
2473           x ^= (~0 << 7);
2474         } else if ((x ^= (buffer[tempPos++] << 14)) >= 0) {
2475           x ^= (~0 << 7) ^ (~0 << 14);
2476         } else if ((x ^= (buffer[tempPos++] << 21)) < 0) {
2477           x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
2478         } else {
2479           int y = buffer[tempPos++];
2480           x ^= y << 28;
2481           x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
2482           if (y < 0
2483               && buffer[tempPos++] < 0
2484               && buffer[tempPos++] < 0
2485               && buffer[tempPos++] < 0
2486               && buffer[tempPos++] < 0
2487               && buffer[tempPos++] < 0) {
2488             break fastpath; // Will throw malformedVarint()
2489           }
2490         }
2491         pos = tempPos;
2492         return x;
2493       }
2494       return (int) readRawVarint64SlowPath();
2495     }
2496
2497     private void skipRawVarint() throws IOException {
2498       if (bufferSize - pos >= MAX_VARINT_SIZE) {
2499         skipRawVarintFastPath();
2500       } else {
2501         skipRawVarintSlowPath();
2502       }
2503     }
2504
2505     private void skipRawVarintFastPath() throws IOException {
2506       for (int i = 0; i < MAX_VARINT_SIZE; i++) {
2507         if (buffer[pos++] >= 0) {
2508           return;
2509         }
2510       }
2511       throw InvalidProtocolBufferException.malformedVarint();
2512     }
2513
2514     private void skipRawVarintSlowPath() throws IOException {
2515       for (int i = 0; i < MAX_VARINT_SIZE; i++) {
2516         if (readRawByte() >= 0) {
2517           return;
2518         }
2519       }
2520       throw InvalidProtocolBufferException.malformedVarint();
2521     }
2522
2523     @Override
2524     public long readRawVarint64() throws IOException {
2525       // Implementation notes:
2526       //
2527       // Optimized for one-byte values, expected to be common.
2528       // The particular code below was selected from various candidates
2529       // empirically, by winning VarintBenchmark.
2530       //
2531       // Sign extension of (signed) Java bytes is usually a nuisance, but
2532       // we exploit it here to more easily obtain the sign of bytes read.
2533       // Instead of cleaning up the sign extension bits by masking eagerly,
2534       // we delay until we find the final (positive) byte, when we clear all
2535       // accumulated bits with one xor.  We depend on javac to constant fold.
2536       fastpath:
2537       {
2538         int tempPos = pos;
2539
2540         if (bufferSize == tempPos) {
2541           break fastpath;
2542         }
2543
2544         final byte[] buffer = this.buffer;
2545         long x;
2546         int y;
2547         if ((y = buffer[tempPos++]) >= 0) {
2548           pos = tempPos;
2549           return y;
2550         } else if (bufferSize - tempPos < 9) {
2551           break fastpath;
2552         } else if ((y ^= (buffer[tempPos++] << 7)) < 0) {
2553           x = y ^ (~0 << 7);
2554         } else if ((y ^= (buffer[tempPos++] << 14)) >= 0) {
2555           x = y ^ ((~0 << 7) ^ (~0 << 14));
2556         } else if ((y ^= (buffer[tempPos++] << 21)) < 0) {
2557           x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
2558         } else if ((x = y ^ ((long) buffer[tempPos++] << 28)) >= 0L) {
2559           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
2560         } else if ((x ^= ((long) buffer[tempPos++] << 35)) < 0L) {
2561           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
2562         } else if ((x ^= ((long) buffer[tempPos++] << 42)) >= 0L) {
2563           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
2564         } else if ((x ^= ((long) buffer[tempPos++] << 49)) < 0L) {
2565           x ^=
2566               (~0L << 7)
2567                   ^ (~0L << 14)
2568                   ^ (~0L << 21)
2569                   ^ (~0L << 28)
2570                   ^ (~0L << 35)
2571                   ^ (~0L << 42)
2572                   ^ (~0L << 49);
2573         } else {
2574           x ^= ((long) buffer[tempPos++] << 56);
2575           x ^=
2576               (~0L << 7)
2577                   ^ (~0L << 14)
2578                   ^ (~0L << 21)
2579                   ^ (~0L << 28)
2580                   ^ (~0L << 35)
2581                   ^ (~0L << 42)
2582                   ^ (~0L << 49)
2583                   ^ (~0L << 56);
2584           if (x < 0L) {
2585             if (buffer[tempPos++] < 0L) {
2586               break fastpath; // Will throw malformedVarint()
2587             }
2588           }
2589         }
2590         pos = tempPos;
2591         return x;
2592       }
2593       return readRawVarint64SlowPath();
2594     }
2595
2596     @Override
2597     long readRawVarint64SlowPath() throws IOException {
2598       long result = 0;
2599       for (int shift = 0; shift < 64; shift += 7) {
2600         final byte b = readRawByte();
2601         result |= (long) (b & 0x7F) << shift;
2602         if ((b & 0x80) == 0) {
2603           return result;
2604         }
2605       }
2606       throw InvalidProtocolBufferException.malformedVarint();
2607     }
2608
2609     @Override
2610     public int readRawLittleEndian32() throws IOException {
2611       int tempPos = pos;
2612
2613       if (bufferSize - tempPos < FIXED32_SIZE) {
2614         refillBuffer(FIXED32_SIZE);
2615         tempPos = pos;
2616       }
2617
2618       final byte[] buffer = this.buffer;
2619       pos = tempPos + FIXED32_SIZE;
2620       return (((buffer[tempPos] & 0xff))
2621           | ((buffer[tempPos + 1] & 0xff) << 8)
2622           | ((buffer[tempPos + 2] & 0xff) << 16)
2623           | ((buffer[tempPos + 3] & 0xff) << 24));
2624     }
2625
2626     @Override
2627     public long readRawLittleEndian64() throws IOException {
2628       int tempPos = pos;
2629
2630       if (bufferSize - tempPos < FIXED64_SIZE) {
2631         refillBuffer(FIXED64_SIZE);
2632         tempPos = pos;
2633       }
2634
2635       final byte[] buffer = this.buffer;
2636       pos = tempPos + FIXED64_SIZE;
2637       return (((buffer[tempPos] & 0xffL))
2638           | ((buffer[tempPos + 1] & 0xffL) << 8)
2639           | ((buffer[tempPos + 2] & 0xffL) << 16)
2640           | ((buffer[tempPos + 3] & 0xffL) << 24)
2641           | ((buffer[tempPos + 4] & 0xffL) << 32)
2642           | ((buffer[tempPos + 5] & 0xffL) << 40)
2643           | ((buffer[tempPos + 6] & 0xffL) << 48)
2644           | ((buffer[tempPos + 7] & 0xffL) << 56));
2645     }
2646
2647     // -----------------------------------------------------------------
2648
2649     @Override
2650     public void enableAliasing(boolean enabled) {
2651       // TODO(nathanmittler): Ideally we should throw here. Do nothing for backward compatibility.
2652     }
2653
2654     @Override
2655     public void resetSizeCounter() {
2656       totalBytesRetired = -pos;
2657     }
2658
2659     @Override
2660     public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
2661       if (byteLimit < 0) {
2662         throw InvalidProtocolBufferException.negativeSize();
2663       }
2664       byteLimit += totalBytesRetired + pos;
2665       final int oldLimit = currentLimit;
2666       if (byteLimit > oldLimit) {
2667         throw InvalidProtocolBufferException.truncatedMessage();
2668       }
2669       currentLimit = byteLimit;
2670
2671       recomputeBufferSizeAfterLimit();
2672
2673       return oldLimit;
2674     }
2675
2676     private void recomputeBufferSizeAfterLimit() {
2677       bufferSize += bufferSizeAfterLimit;
2678       final int bufferEnd = totalBytesRetired + bufferSize;
2679       if (bufferEnd > currentLimit) {
2680         // Limit is in current buffer.
2681         bufferSizeAfterLimit = bufferEnd - currentLimit;
2682         bufferSize -= bufferSizeAfterLimit;
2683       } else {
2684         bufferSizeAfterLimit = 0;
2685       }
2686     }
2687
2688     @Override
2689     public void popLimit(final int oldLimit) {
2690       currentLimit = oldLimit;
2691       recomputeBufferSizeAfterLimit();
2692     }
2693
2694     @Override
2695     public int getBytesUntilLimit() {
2696       if (currentLimit == Integer.MAX_VALUE) {
2697         return -1;
2698       }
2699
2700       final int currentAbsolutePosition = totalBytesRetired + pos;
2701       return currentLimit - currentAbsolutePosition;
2702     }
2703
2704     @Override
2705     public boolean isAtEnd() throws IOException {
2706       return pos == bufferSize && !tryRefillBuffer(1);
2707     }
2708
2709     @Override
2710     public int getTotalBytesRead() {
2711       return totalBytesRetired + pos;
2712     }
2713
2714     private interface RefillCallback {
2715       void onRefill();
2716     }
2717
2718     private RefillCallback refillCallback = null;
2719
2720     /**
2721      * Reads more bytes from the input, making at least {@code n} bytes available in the buffer.
2722      * Caller must ensure that the requested space is not yet available, and that the requested
2723      * space is less than BUFFER_SIZE.
2724      *
2725      * @throws InvalidProtocolBufferException The end of the stream or the current limit was
2726      *     reached.
2727      */
2728     private void refillBuffer(int n) throws IOException {
2729       if (!tryRefillBuffer(n)) {
2730         // We have to distinguish the exception between sizeLimitExceeded and truncatedMessage. So
2731         // we just throw an sizeLimitExceeded exception here if it exceeds the sizeLimit
2732         if (n > sizeLimit - totalBytesRetired - pos) {
2733           throw InvalidProtocolBufferException.sizeLimitExceeded();
2734         } else {
2735           throw InvalidProtocolBufferException.truncatedMessage();
2736         }
2737       }
2738     }
2739
2740     /**
2741      * Tries to read more bytes from the input, making at least {@code n} bytes available in the
2742      * buffer. Caller must ensure that the requested space is not yet available, and that the
2743      * requested space is less than BUFFER_SIZE.
2744      *
2745      * @return {@code true} If the bytes could be made available; {@code false} 1. Current at the
2746      *     end of the stream 2. The current limit was reached 3. The total size limit was reached
2747      */
2748     private boolean tryRefillBuffer(int n) throws IOException {
2749       if (pos + n <= bufferSize) {
2750         throw new IllegalStateException(
2751             "refillBuffer() called when " + n + " bytes were already available in buffer");
2752       }
2753
2754       // Check whether the size of total message needs to read is bigger than the size limit.
2755       // We shouldn't throw an exception here as isAtEnd() function needs to get this function's
2756       // return as the result.
2757       if (n > sizeLimit - totalBytesRetired - pos) {
2758         return false;
2759       }
2760
2761       // Shouldn't throw the exception here either.
2762       if (totalBytesRetired + pos + n > currentLimit) {
2763         // Oops, we hit a limit.
2764         return false;
2765       }
2766
2767       if (refillCallback != null) {
2768         refillCallback.onRefill();
2769       }
2770
2771       int tempPos = pos;
2772       if (tempPos > 0) {
2773         if (bufferSize > tempPos) {
2774           System.arraycopy(buffer, tempPos, buffer, 0, bufferSize - tempPos);
2775         }
2776         totalBytesRetired += tempPos;
2777         bufferSize -= tempPos;
2778         pos = 0;
2779       }
2780
2781       // Here we should refill the buffer as many bytes as possible.
2782       int bytesRead =
2783           input.read(
2784               buffer,
2785               bufferSize,
2786               Math.min(
2787                   //  the size of allocated but unused bytes in the buffer
2788                   buffer.length - bufferSize,
2789                   //  do not exceed the total bytes limit
2790                   sizeLimit - totalBytesRetired - bufferSize));
2791       if (bytesRead == 0 || bytesRead < -1 || bytesRead > buffer.length) {
2792         throw new IllegalStateException(
2793             input.getClass()
2794                 + "#read(byte[]) returned invalid result: "
2795                 + bytesRead
2796                 + "\nThe InputStream implementation is buggy.");
2797       }
2798       if (bytesRead > 0) {
2799         bufferSize += bytesRead;
2800         recomputeBufferSizeAfterLimit();
2801         return (bufferSize >= n) ? true : tryRefillBuffer(n);
2802       }
2803
2804       return false;
2805     }
2806
2807     @Override
2808     public byte readRawByte() throws IOException {
2809       if (pos == bufferSize) {
2810         refillBuffer(1);
2811       }
2812       return buffer[pos++];
2813     }
2814
2815     @Override
2816     public byte[] readRawBytes(final int size) throws IOException {
2817       final int tempPos = pos;
2818       if (size <= (bufferSize - tempPos) && size > 0) {
2819         pos = tempPos + size;
2820         return Arrays.copyOfRange(buffer, tempPos, tempPos + size);
2821       } else {
2822         // TODO(dweis): Do we want to protect from malicious input streams here?
2823         return readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ false);
2824       }
2825     }
2826
2827     /**
2828      * Exactly like readRawBytes, but caller must have already checked the fast path: (size <=
2829      * (bufferSize - pos) && size > 0)
2830      * 
2831      * If ensureNoLeakedReferences is true, the value is guaranteed to have not escaped to
2832      * untrusted code.
2833      */
2834     private byte[] readRawBytesSlowPath(
2835         final int size, boolean ensureNoLeakedReferences) throws IOException {
2836       // Attempt to read the data in one byte array when it's safe to do.
2837       byte[] result = readRawBytesSlowPathOneChunk(size);
2838       if (result != null) {
2839         return ensureNoLeakedReferences ? result.clone() : result;
2840       }
2841
2842       final int originalBufferPos = pos;
2843       final int bufferedBytes = bufferSize - pos;
2844
2845       // Mark the current buffer consumed.
2846       totalBytesRetired += bufferSize;
2847       pos = 0;
2848       bufferSize = 0;
2849
2850       // Determine the number of bytes we need to read from the input stream.
2851       int sizeLeft = size - bufferedBytes;
2852
2853       // The size is very large. For security reasons we read them in small
2854       // chunks.
2855       List<byte[]> chunks = readRawBytesSlowPathRemainingChunks(sizeLeft);
2856
2857       // OK, got everything.  Now concatenate it all into one buffer.
2858       final byte[] bytes = new byte[size];
2859
2860       // Start by copying the leftover bytes from this.buffer.
2861       System.arraycopy(buffer, originalBufferPos, bytes, 0, bufferedBytes);
2862
2863       // And now all the chunks.
2864       int tempPos = bufferedBytes;
2865       for (final byte[] chunk : chunks) {
2866         System.arraycopy(chunk, 0, bytes, tempPos, chunk.length);
2867         tempPos += chunk.length;
2868       }
2869
2870       // Done.
2871       return bytes;
2872     }
2873
2874     /**
2875      * Attempts to read the data in one byte array when it's safe to do. Returns null if the size to
2876      * read is too large and needs to be allocated in smaller chunks for security reasons.
2877      * 
2878      * Returns a byte[] that may have escaped to user code via InputStream APIs.
2879      */
2880     private byte[] readRawBytesSlowPathOneChunk(final int size) throws IOException {
2881       if (size == 0) {
2882         return Internal.EMPTY_BYTE_ARRAY;
2883       }
2884       if (size < 0) {
2885         throw InvalidProtocolBufferException.negativeSize();
2886       }
2887
2888       // Integer-overflow-conscious check that the message size so far has not exceeded sizeLimit.
2889       int currentMessageSize = totalBytesRetired + pos + size;
2890       if (currentMessageSize - sizeLimit > 0) {
2891         throw InvalidProtocolBufferException.sizeLimitExceeded();
2892       }
2893
2894       // Verify that the message size so far has not exceeded currentLimit.
2895       if (currentMessageSize > currentLimit) {
2896         // Read to the end of the stream anyway.
2897         skipRawBytes(currentLimit - totalBytesRetired - pos);
2898         throw InvalidProtocolBufferException.truncatedMessage();
2899       }
2900
2901       final int bufferedBytes = bufferSize - pos;
2902       // Determine the number of bytes we need to read from the input stream.
2903       int sizeLeft = size - bufferedBytes;
2904       // TODO(nathanmittler): Consider using a value larger than DEFAULT_BUFFER_SIZE.
2905       if (sizeLeft < DEFAULT_BUFFER_SIZE || sizeLeft <= input.available()) {
2906         // Either the bytes we need are known to be available, or the required buffer is
2907         // within an allowed threshold - go ahead and allocate the buffer now.
2908         final byte[] bytes = new byte[size];
2909
2910         // Copy all of the buffered bytes to the result buffer.
2911         System.arraycopy(buffer, pos, bytes, 0, bufferedBytes);
2912         totalBytesRetired += bufferSize;
2913         pos = 0;
2914         bufferSize = 0;
2915
2916         // Fill the remaining bytes from the input stream.
2917         int tempPos = bufferedBytes;
2918         while (tempPos < bytes.length) {
2919           int n = input.read(bytes, tempPos, size - tempPos);
2920           if (n == -1) {
2921             throw InvalidProtocolBufferException.truncatedMessage();
2922           }
2923           totalBytesRetired += n;
2924           tempPos += n;
2925         }
2926
2927         return bytes;
2928       }
2929
2930       return null;
2931     }
2932
2933     /**
2934      * Reads the remaining data in small chunks from the input stream.
2935      * 
2936      * Returns a byte[] that may have escaped to user code via InputStream APIs.
2937      */
2938     private List<byte[]> readRawBytesSlowPathRemainingChunks(int sizeLeft) throws IOException {
2939       // The size is very large.  For security reasons, we can't allocate the
2940       // entire byte array yet.  The size comes directly from the input, so a
2941       // maliciously-crafted message could provide a bogus very large size in
2942       // order to trick the app into allocating a lot of memory.  We avoid this
2943       // by allocating and reading only a small chunk at a time, so that the
2944       // malicious message must actually *be* extremely large to cause
2945       // problems.  Meanwhile, we limit the allowed size of a message elsewhere.
2946       final List<byte[]> chunks = new ArrayList<byte[]>();
2947
2948       while (sizeLeft > 0) {
2949         // TODO(nathanmittler): Consider using a value larger than DEFAULT_BUFFER_SIZE.
2950         final byte[] chunk = new byte[Math.min(sizeLeft, DEFAULT_BUFFER_SIZE)];
2951         int tempPos = 0;
2952         while (tempPos < chunk.length) {
2953           final int n = input.read(chunk, tempPos, chunk.length - tempPos);
2954           if (n == -1) {
2955             throw InvalidProtocolBufferException.truncatedMessage();
2956           }
2957           totalBytesRetired += n;
2958           tempPos += n;
2959         }
2960         sizeLeft -= chunk.length;
2961         chunks.add(chunk);
2962       }
2963
2964       return chunks;
2965     }
2966
2967     /**
2968      * Like readBytes, but caller must have already checked the fast path: (size <= (bufferSize -
2969      * pos) && size > 0 || size == 0)
2970      */
2971     private ByteString readBytesSlowPath(final int size) throws IOException {
2972       final byte[] result = readRawBytesSlowPathOneChunk(size);
2973       if (result != null) {
2974         // We must copy as the byte array was handed off to the InputStream and a malicious
2975         // implementation could retain a reference.
2976         return ByteString.copyFrom(result);
2977       }
2978
2979       final int originalBufferPos = pos;
2980       final int bufferedBytes = bufferSize - pos;
2981
2982       // Mark the current buffer consumed.
2983       totalBytesRetired += bufferSize;
2984       pos = 0;
2985       bufferSize = 0;
2986
2987       // Determine the number of bytes we need to read from the input stream.
2988       int sizeLeft = size - bufferedBytes;
2989
2990       // The size is very large. For security reasons we read them in small
2991       // chunks.
2992       List<byte[]> chunks = readRawBytesSlowPathRemainingChunks(sizeLeft);
2993
2994       // OK, got everything.  Now concatenate it all into one buffer.
2995       final byte[] bytes = new byte[size];
2996
2997       // Start by copying the leftover bytes from this.buffer.
2998       System.arraycopy(buffer, originalBufferPos, bytes, 0, bufferedBytes);
2999
3000       // And now all the chunks.
3001       int tempPos = bufferedBytes;
3002       for (final byte[] chunk : chunks) {
3003         System.arraycopy(chunk, 0, bytes, tempPos, chunk.length);
3004         tempPos += chunk.length;
3005       }
3006       
3007       return ByteString.wrap(bytes);
3008     }
3009
3010     @Override
3011     public void skipRawBytes(final int size) throws IOException {
3012       if (size <= (bufferSize - pos) && size >= 0) {
3013         // We have all the bytes we need already.
3014         pos += size;
3015       } else {
3016         skipRawBytesSlowPath(size);
3017       }
3018     }
3019
3020     /**
3021      * Exactly like skipRawBytes, but caller must have already checked the fast path: (size <=
3022      * (bufferSize - pos) && size >= 0)
3023      */
3024     private void skipRawBytesSlowPath(final int size) throws IOException {
3025       if (size < 0) {
3026         throw InvalidProtocolBufferException.negativeSize();
3027       }
3028
3029       if (totalBytesRetired + pos + size > currentLimit) {
3030         // Read to the end of the stream anyway.
3031         skipRawBytes(currentLimit - totalBytesRetired - pos);
3032         // Then fail.
3033         throw InvalidProtocolBufferException.truncatedMessage();
3034       }
3035
3036       int totalSkipped = 0;
3037       if (refillCallback == null) {
3038         // Skipping more bytes than are in the buffer.  First skip what we have.
3039         totalBytesRetired += pos;
3040         totalSkipped = bufferSize - pos;
3041         bufferSize = 0;
3042         pos = 0;
3043
3044         try {
3045           while (totalSkipped < size) {
3046             int toSkip = size - totalSkipped;
3047             long skipped = input.skip(toSkip);
3048             if (skipped < 0 || skipped > toSkip) {
3049               throw new IllegalStateException(
3050                   input.getClass()
3051                       + "#skip returned invalid result: "
3052                       + skipped
3053                       + "\nThe InputStream implementation is buggy.");
3054             } else if (skipped == 0) {
3055               // The API contract of skip() permits an inputstream to skip zero bytes for any reason
3056               // it wants. In particular, ByteArrayInputStream will just return zero over and over
3057               // when it's at the end of its input. In order to actually confirm that we've hit the
3058               // end of input, we need to issue a read call via the other path.
3059               break;
3060             }
3061             totalSkipped += (int) skipped;
3062           }
3063         } finally {
3064           totalBytesRetired += totalSkipped;
3065           recomputeBufferSizeAfterLimit();
3066         }
3067       }
3068       if (totalSkipped < size) {
3069         // Skipping more bytes than are in the buffer.  First skip what we have.
3070         int tempPos = bufferSize - pos;
3071         pos = bufferSize;
3072
3073         // Keep refilling the buffer until we get to the point we wanted to skip to.
3074         // This has the side effect of ensuring the limits are updated correctly.
3075         refillBuffer(1);
3076         while (size - tempPos > bufferSize) {
3077           tempPos += bufferSize;
3078           pos = bufferSize;
3079           refillBuffer(1);
3080         }
3081
3082         pos = size - tempPos;
3083       }
3084     }
3085   }
3086
3087   /**
3088    * Implementation of {@link CodedInputStream} that uses an {@link Iterable <ByteBuffer>} as the
3089    * data source. Requires the use of {@code sun.misc.Unsafe} to perform fast reads on the buffer.
3090    */
3091   private static final class IterableDirectByteBufferDecoder extends CodedInputStream {
3092     /** The object that need to decode. */
3093     private Iterable<ByteBuffer> input;
3094     /** The {@link Iterator} with type {@link ByteBuffer} of {@code input} */
3095     private Iterator<ByteBuffer> iterator;
3096     /** The current ByteBuffer; */
3097     private ByteBuffer currentByteBuffer;
3098     /**
3099      * If {@code true}, indicates that all the buffer are backing a {@link ByteString} and are
3100      * therefore considered to be an immutable input source.
3101      */
3102     private boolean immutable;
3103     /**
3104      * If {@code true}, indicates that calls to read {@link ByteString} or {@code byte[]}
3105      * <strong>may</strong> return slices of the underlying buffer, rather than copies.
3106      */
3107     private boolean enableAliasing;
3108     /** The global total message length limit */
3109     private int totalBufferSize;
3110     /** The amount of available data in the input beyond {@link #currentLimit}. */
3111     private int bufferSizeAfterCurrentLimit;
3112     /** The absolute position of the end of the current message. */
3113     private int currentLimit = Integer.MAX_VALUE;
3114     /** The last tag that was read from this stream. */
3115     private int lastTag;
3116     /** Total Bytes have been Read from the {@link Iterable} {@link ByteBuffer} */
3117     private int totalBytesRead;
3118     /** The start position offset of the whole message, used as to reset the totalBytesRead */
3119     private int startOffset;
3120     /** The current position for current ByteBuffer */
3121     private long currentByteBufferPos;
3122
3123     private long currentByteBufferStartPos;
3124     /**
3125      * If the current ByteBuffer is unsafe-direct based, currentAddress is the start address of this
3126      * ByteBuffer; otherwise should be zero.
3127      */
3128     private long currentAddress;
3129     /** The limit position for current ByteBuffer */
3130     private long currentByteBufferLimit;
3131
3132     /**
3133      * The constructor of {@code Iterable<ByteBuffer>} decoder.
3134      *
3135      * @param inputBufs The input data.
3136      * @param size The total size of the input data.
3137      * @param immutableFlag whether the input data is immutable.
3138      */
3139     private IterableDirectByteBufferDecoder(
3140         Iterable<ByteBuffer> inputBufs, int size, boolean immutableFlag) {
3141       totalBufferSize = size;
3142       input = inputBufs;
3143       iterator = input.iterator();
3144       immutable = immutableFlag;
3145       startOffset = totalBytesRead = 0;
3146       if (size == 0) {
3147         currentByteBuffer = EMPTY_BYTE_BUFFER;
3148         currentByteBufferPos = 0;
3149         currentByteBufferStartPos = 0;
3150         currentByteBufferLimit = 0;
3151         currentAddress = 0;
3152       } else {
3153         tryGetNextByteBuffer();
3154       }
3155     }
3156
3157     /** To get the next ByteBuffer from {@code input}, and then update the parameters */
3158     private void getNextByteBuffer() throws InvalidProtocolBufferException {
3159       if (!iterator.hasNext()) {
3160         throw InvalidProtocolBufferException.truncatedMessage();
3161       }
3162       tryGetNextByteBuffer();
3163     }
3164
3165     private void tryGetNextByteBuffer() {
3166       currentByteBuffer = iterator.next();
3167       totalBytesRead += (int) (currentByteBufferPos - currentByteBufferStartPos);
3168       currentByteBufferPos = currentByteBuffer.position();
3169       currentByteBufferStartPos = currentByteBufferPos;
3170       currentByteBufferLimit = currentByteBuffer.limit();
3171       currentAddress = UnsafeUtil.addressOffset(currentByteBuffer);
3172       currentByteBufferPos += currentAddress;
3173       currentByteBufferStartPos += currentAddress;
3174       currentByteBufferLimit += currentAddress;
3175     }
3176
3177     @Override
3178     public int readTag() throws IOException {
3179       if (isAtEnd()) {
3180         lastTag = 0;
3181         return 0;
3182       }
3183
3184       lastTag = readRawVarint32();
3185       if (WireFormat.getTagFieldNumber(lastTag) == 0) {
3186         // If we actually read zero (or any tag number corresponding to field
3187         // number zero), that's not a valid tag.
3188         throw InvalidProtocolBufferException.invalidTag();
3189       }
3190       return lastTag;
3191     }
3192
3193     @Override
3194     public void checkLastTagWas(final int value) throws InvalidProtocolBufferException {
3195       if (lastTag != value) {
3196         throw InvalidProtocolBufferException.invalidEndTag();
3197       }
3198     }
3199
3200     @Override
3201     public int getLastTag() {
3202       return lastTag;
3203     }
3204
3205     @Override
3206     public boolean skipField(final int tag) throws IOException {
3207       switch (WireFormat.getTagWireType(tag)) {
3208         case WireFormat.WIRETYPE_VARINT:
3209           skipRawVarint();
3210           return true;
3211         case WireFormat.WIRETYPE_FIXED64:
3212           skipRawBytes(FIXED64_SIZE);
3213           return true;
3214         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
3215           skipRawBytes(readRawVarint32());
3216           return true;
3217         case WireFormat.WIRETYPE_START_GROUP:
3218           skipMessage();
3219           checkLastTagWas(
3220               WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
3221           return true;
3222         case WireFormat.WIRETYPE_END_GROUP:
3223           return false;
3224         case WireFormat.WIRETYPE_FIXED32:
3225           skipRawBytes(FIXED32_SIZE);
3226           return true;
3227         default:
3228           throw InvalidProtocolBufferException.invalidWireType();
3229       }
3230     }
3231
3232     @Override
3233     public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
3234       switch (WireFormat.getTagWireType(tag)) {
3235         case WireFormat.WIRETYPE_VARINT:
3236           {
3237             long value = readInt64();
3238             output.writeRawVarint32(tag);
3239             output.writeUInt64NoTag(value);
3240             return true;
3241           }
3242         case WireFormat.WIRETYPE_FIXED64:
3243           {
3244             long value = readRawLittleEndian64();
3245             output.writeRawVarint32(tag);
3246             output.writeFixed64NoTag(value);
3247             return true;
3248           }
3249         case WireFormat.WIRETYPE_LENGTH_DELIMITED:
3250           {
3251             ByteString value = readBytes();
3252             output.writeRawVarint32(tag);
3253             output.writeBytesNoTag(value);
3254             return true;
3255           }
3256         case WireFormat.WIRETYPE_START_GROUP:
3257           {
3258             output.writeRawVarint32(tag);
3259             skipMessage(output);
3260             int endtag =
3261                 WireFormat.makeTag(
3262                     WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
3263             checkLastTagWas(endtag);
3264             output.writeRawVarint32(endtag);
3265             return true;
3266           }
3267         case WireFormat.WIRETYPE_END_GROUP:
3268           {
3269             return false;
3270           }
3271         case WireFormat.WIRETYPE_FIXED32:
3272           {
3273             int value = readRawLittleEndian32();
3274             output.writeRawVarint32(tag);
3275             output.writeFixed32NoTag(value);
3276             return true;
3277           }
3278         default:
3279           throw InvalidProtocolBufferException.invalidWireType();
3280       }
3281     }
3282
3283     @Override
3284     public void skipMessage() throws IOException {
3285       while (true) {
3286         final int tag = readTag();
3287         if (tag == 0 || !skipField(tag)) {
3288           return;
3289         }
3290       }
3291     }
3292
3293     @Override
3294     public void skipMessage(CodedOutputStream output) throws IOException {
3295       while (true) {
3296         final int tag = readTag();
3297         if (tag == 0 || !skipField(tag, output)) {
3298           return;
3299         }
3300       }
3301     }
3302
3303     // -----------------------------------------------------------------
3304
3305     @Override
3306     public double readDouble() throws IOException {
3307       return Double.longBitsToDouble(readRawLittleEndian64());
3308     }
3309
3310     @Override
3311     public float readFloat() throws IOException {
3312       return Float.intBitsToFloat(readRawLittleEndian32());
3313     }
3314
3315     @Override
3316     public long readUInt64() throws IOException {
3317       return readRawVarint64();
3318     }
3319
3320     @Override
3321     public long readInt64() throws IOException {
3322       return readRawVarint64();
3323     }
3324
3325     @Override
3326     public int readInt32() throws IOException {
3327       return readRawVarint32();
3328     }
3329
3330     @Override
3331     public long readFixed64() throws IOException {
3332       return readRawLittleEndian64();
3333     }
3334
3335     @Override
3336     public int readFixed32() throws IOException {
3337       return readRawLittleEndian32();
3338     }
3339
3340     @Override
3341     public boolean readBool() throws IOException {
3342       return readRawVarint64() != 0;
3343     }
3344
3345     @Override
3346     public String readString() throws IOException {
3347       final int size = readRawVarint32();
3348       if (size > 0 && size <= currentByteBufferLimit - currentByteBufferPos) {
3349         byte[] bytes = new byte[size];
3350         UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, size);
3351         String result = new String(bytes, UTF_8);
3352         currentByteBufferPos += size;
3353         return result;
3354       } else if (size > 0 && size <= remaining()) {
3355         // TODO(yilunchong): To use an underlying bytes[] instead of allocating a new bytes[]
3356         byte[] bytes = new byte[size];
3357         readRawBytesTo(bytes, 0, size);
3358         String result = new String(bytes, UTF_8);
3359         return result;
3360       }
3361
3362       if (size == 0) {
3363         return "";
3364       }
3365       if (size < 0) {
3366         throw InvalidProtocolBufferException.negativeSize();
3367       }
3368       throw InvalidProtocolBufferException.truncatedMessage();
3369     }
3370
3371     @Override
3372     public String readStringRequireUtf8() throws IOException {
3373       final int size = readRawVarint32();
3374       if (size > 0 && size <= currentByteBufferLimit - currentByteBufferPos) {
3375         final int bufferPos = (int) (currentByteBufferPos - currentByteBufferStartPos);
3376         String result = Utf8.decodeUtf8(currentByteBuffer, bufferPos, size);
3377         currentByteBufferPos += size;
3378         return result;
3379       }
3380       if (size >= 0 && size <= remaining()) {
3381         byte[] bytes = new byte[size];
3382         readRawBytesTo(bytes, 0, size);
3383         return Utf8.decodeUtf8(bytes, 0, size);
3384       }
3385
3386       if (size == 0) {
3387         return "";
3388       }
3389       if (size <= 0) {
3390         throw InvalidProtocolBufferException.negativeSize();
3391       }
3392       throw InvalidProtocolBufferException.truncatedMessage();
3393     }
3394
3395     @Override
3396     public void readGroup(
3397         final int fieldNumber,
3398         final MessageLite.Builder builder,
3399         final ExtensionRegistryLite extensionRegistry)
3400         throws IOException {
3401       if (recursionDepth >= recursionLimit) {
3402         throw InvalidProtocolBufferException.recursionLimitExceeded();
3403       }
3404       ++recursionDepth;
3405       builder.mergeFrom(this, extensionRegistry);
3406       checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
3407       --recursionDepth;
3408     }
3409
3410
3411     @Override
3412     public <T extends MessageLite> T readGroup(
3413         final int fieldNumber,
3414         final Parser<T> parser,
3415         final ExtensionRegistryLite extensionRegistry)
3416         throws IOException {
3417       if (recursionDepth >= recursionLimit) {
3418         throw InvalidProtocolBufferException.recursionLimitExceeded();
3419       }
3420       ++recursionDepth;
3421       T result = parser.parsePartialFrom(this, extensionRegistry);
3422       checkLastTagWas(WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
3423       --recursionDepth;
3424       return result;
3425     }
3426
3427     @Deprecated
3428     @Override
3429     public void readUnknownGroup(final int fieldNumber, final MessageLite.Builder builder)
3430         throws IOException {
3431       readGroup(fieldNumber, builder, ExtensionRegistryLite.getEmptyRegistry());
3432     }
3433
3434     @Override
3435     public void readMessage(
3436         final MessageLite.Builder builder, final ExtensionRegistryLite extensionRegistry)
3437         throws IOException {
3438       final int length = readRawVarint32();
3439       if (recursionDepth >= recursionLimit) {
3440         throw InvalidProtocolBufferException.recursionLimitExceeded();
3441       }
3442       final int oldLimit = pushLimit(length);
3443       ++recursionDepth;
3444       builder.mergeFrom(this, extensionRegistry);
3445       checkLastTagWas(0);
3446       --recursionDepth;
3447       popLimit(oldLimit);
3448     }
3449
3450
3451     @Override
3452     public <T extends MessageLite> T readMessage(
3453         final Parser<T> parser, final ExtensionRegistryLite extensionRegistry) throws IOException {
3454       int length = readRawVarint32();
3455       if (recursionDepth >= recursionLimit) {
3456         throw InvalidProtocolBufferException.recursionLimitExceeded();
3457       }
3458       final int oldLimit = pushLimit(length);
3459       ++recursionDepth;
3460       T result = parser.parsePartialFrom(this, extensionRegistry);
3461       checkLastTagWas(0);
3462       --recursionDepth;
3463       popLimit(oldLimit);
3464       return result;
3465     }
3466
3467     @Override
3468     public ByteString readBytes() throws IOException {
3469       final int size = readRawVarint32();
3470       if (size > 0 && size <= currentByteBufferLimit - currentByteBufferPos) {
3471         if (immutable && enableAliasing) {
3472           final int idx = (int) (currentByteBufferPos - currentAddress);
3473           final ByteString result = ByteString.wrap(slice(idx, idx + size));
3474           currentByteBufferPos += size;
3475           return result;
3476         } else {
3477           byte[] bytes;
3478           bytes = new byte[size];
3479           UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, size);
3480           currentByteBufferPos += size;
3481           return ByteString.wrap(bytes);
3482         }
3483       } else if (size > 0 && size <= remaining()) {
3484         byte[] temp = new byte[size];
3485         readRawBytesTo(temp, 0, size);
3486         return ByteString.wrap(temp);
3487       }
3488
3489       if (size == 0) {
3490         return ByteString.EMPTY;
3491       }
3492       if (size < 0) {
3493         throw InvalidProtocolBufferException.negativeSize();
3494       }
3495       throw InvalidProtocolBufferException.truncatedMessage();
3496     }
3497
3498     @Override
3499     public byte[] readByteArray() throws IOException {
3500       return readRawBytes(readRawVarint32());
3501     }
3502
3503     @Override
3504     public ByteBuffer readByteBuffer() throws IOException {
3505       final int size = readRawVarint32();
3506       if (size > 0 && size <= currentRemaining()) {
3507         if (!immutable && enableAliasing) {
3508           currentByteBufferPos += size;
3509           return slice(
3510               (int) (currentByteBufferPos - currentAddress - size),
3511               (int) (currentByteBufferPos - currentAddress));
3512         } else {
3513           byte[] bytes = new byte[size];
3514           UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, size);
3515           currentByteBufferPos += size;
3516           return ByteBuffer.wrap(bytes);
3517         }
3518       } else if (size > 0 && size <= remaining()) {
3519         byte[] temp = new byte[size];
3520         readRawBytesTo(temp, 0, size);
3521         return ByteBuffer.wrap(temp);
3522       }
3523
3524       if (size == 0) {
3525         return EMPTY_BYTE_BUFFER;
3526       }
3527       if (size < 0) {
3528         throw InvalidProtocolBufferException.negativeSize();
3529       }
3530       throw InvalidProtocolBufferException.truncatedMessage();
3531     }
3532
3533     @Override
3534     public int readUInt32() throws IOException {
3535       return readRawVarint32();
3536     }
3537
3538     @Override
3539     public int readEnum() throws IOException {
3540       return readRawVarint32();
3541     }
3542
3543     @Override
3544     public int readSFixed32() throws IOException {
3545       return readRawLittleEndian32();
3546     }
3547
3548     @Override
3549     public long readSFixed64() throws IOException {
3550       return readRawLittleEndian64();
3551     }
3552
3553     @Override
3554     public int readSInt32() throws IOException {
3555       return decodeZigZag32(readRawVarint32());
3556     }
3557
3558     @Override
3559     public long readSInt64() throws IOException {
3560       return decodeZigZag64(readRawVarint64());
3561     }
3562
3563     @Override
3564     public int readRawVarint32() throws IOException {
3565       fastpath:
3566       {
3567         long tempPos = currentByteBufferPos;
3568
3569         if (currentByteBufferLimit == currentByteBufferPos) {
3570           break fastpath;
3571         }
3572
3573         int x;
3574         if ((x = UnsafeUtil.getByte(tempPos++)) >= 0) {
3575           currentByteBufferPos++;
3576           return x;
3577         } else if (currentByteBufferLimit - currentByteBufferPos < 10) {
3578           break fastpath;
3579         } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 7)) < 0) {
3580           x ^= (~0 << 7);
3581         } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 14)) >= 0) {
3582           x ^= (~0 << 7) ^ (~0 << 14);
3583         } else if ((x ^= (UnsafeUtil.getByte(tempPos++) << 21)) < 0) {
3584           x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
3585         } else {
3586           int y = UnsafeUtil.getByte(tempPos++);
3587           x ^= y << 28;
3588           x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
3589           if (y < 0
3590               && UnsafeUtil.getByte(tempPos++) < 0
3591               && UnsafeUtil.getByte(tempPos++) < 0
3592               && UnsafeUtil.getByte(tempPos++) < 0
3593               && UnsafeUtil.getByte(tempPos++) < 0
3594               && UnsafeUtil.getByte(tempPos++) < 0) {
3595             break fastpath; // Will throw malformedVarint()
3596           }
3597         }
3598         currentByteBufferPos = tempPos;
3599         return x;
3600       }
3601       return (int) readRawVarint64SlowPath();
3602     }
3603
3604     @Override
3605     public long readRawVarint64() throws IOException {
3606       fastpath:
3607       {
3608         long tempPos = currentByteBufferPos;
3609
3610         if (currentByteBufferLimit == currentByteBufferPos) {
3611           break fastpath;
3612         }
3613
3614         long x;
3615         int y;
3616         if ((y = UnsafeUtil.getByte(tempPos++)) >= 0) {
3617           currentByteBufferPos++;
3618           return y;
3619         } else if (currentByteBufferLimit - currentByteBufferPos < 10) {
3620           break fastpath;
3621         } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 7)) < 0) {
3622           x = y ^ (~0 << 7);
3623         } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 14)) >= 0) {
3624           x = y ^ ((~0 << 7) ^ (~0 << 14));
3625         } else if ((y ^= (UnsafeUtil.getByte(tempPos++) << 21)) < 0) {
3626           x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
3627         } else if ((x = y ^ ((long) UnsafeUtil.getByte(tempPos++) << 28)) >= 0L) {
3628           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
3629         } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 35)) < 0L) {
3630           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
3631         } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 42)) >= 0L) {
3632           x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
3633         } else if ((x ^= ((long) UnsafeUtil.getByte(tempPos++) << 49)) < 0L) {
3634           x ^=
3635               (~0L << 7)
3636                   ^ (~0L << 14)
3637                   ^ (~0L << 21)
3638                   ^ (~0L << 28)
3639                   ^ (~0L << 35)
3640                   ^ (~0L << 42)
3641                   ^ (~0L << 49);
3642         } else {
3643           x ^= ((long) UnsafeUtil.getByte(tempPos++) << 56);
3644           x ^=
3645               (~0L << 7)
3646                   ^ (~0L << 14)
3647                   ^ (~0L << 21)
3648                   ^ (~0L << 28)
3649                   ^ (~0L << 35)
3650                   ^ (~0L << 42)
3651                   ^ (~0L << 49)
3652                   ^ (~0L << 56);
3653           if (x < 0L) {
3654             if (UnsafeUtil.getByte(tempPos++) < 0L) {
3655               break fastpath; // Will throw malformedVarint()
3656             }
3657           }
3658         }
3659         currentByteBufferPos = tempPos;
3660         return x;
3661       }
3662       return readRawVarint64SlowPath();
3663     }
3664
3665     @Override
3666     long readRawVarint64SlowPath() throws IOException {
3667       long result = 0;
3668       for (int shift = 0; shift < 64; shift += 7) {
3669         final byte b = readRawByte();
3670         result |= (long) (b & 0x7F) << shift;
3671         if ((b & 0x80) == 0) {
3672           return result;
3673         }
3674       }
3675       throw InvalidProtocolBufferException.malformedVarint();
3676     }
3677
3678     @Override
3679     public int readRawLittleEndian32() throws IOException {
3680       if (currentRemaining() >= FIXED32_SIZE) {
3681         long tempPos = currentByteBufferPos;
3682         currentByteBufferPos += FIXED32_SIZE;
3683         return (((UnsafeUtil.getByte(tempPos) & 0xff))
3684             | ((UnsafeUtil.getByte(tempPos + 1) & 0xff) << 8)
3685             | ((UnsafeUtil.getByte(tempPos + 2) & 0xff) << 16)
3686             | ((UnsafeUtil.getByte(tempPos + 3) & 0xff) << 24));
3687       }
3688       return ((readRawByte() & 0xff)
3689           | ((readRawByte() & 0xff) << 8)
3690           | ((readRawByte() & 0xff) << 16)
3691           | ((readRawByte() & 0xff) << 24));
3692     }
3693
3694     @Override
3695     public long readRawLittleEndian64() throws IOException {
3696       if (currentRemaining() >= FIXED64_SIZE) {
3697         long tempPos = currentByteBufferPos;
3698         currentByteBufferPos += FIXED64_SIZE;
3699         return (((UnsafeUtil.getByte(tempPos) & 0xffL))
3700             | ((UnsafeUtil.getByte(tempPos + 1) & 0xffL) << 8)
3701             | ((UnsafeUtil.getByte(tempPos + 2) & 0xffL) << 16)
3702             | ((UnsafeUtil.getByte(tempPos + 3) & 0xffL) << 24)
3703             | ((UnsafeUtil.getByte(tempPos + 4) & 0xffL) << 32)
3704             | ((UnsafeUtil.getByte(tempPos + 5) & 0xffL) << 40)
3705             | ((UnsafeUtil.getByte(tempPos + 6) & 0xffL) << 48)
3706             | ((UnsafeUtil.getByte(tempPos + 7) & 0xffL) << 56));
3707       }
3708       return ((readRawByte() & 0xffL)
3709           | ((readRawByte() & 0xffL) << 8)
3710           | ((readRawByte() & 0xffL) << 16)
3711           | ((readRawByte() & 0xffL) << 24)
3712           | ((readRawByte() & 0xffL) << 32)
3713           | ((readRawByte() & 0xffL) << 40)
3714           | ((readRawByte() & 0xffL) << 48)
3715           | ((readRawByte() & 0xffL) << 56));
3716     }
3717
3718     @Override
3719     public void enableAliasing(boolean enabled) {
3720       this.enableAliasing = enabled;
3721     }
3722
3723     @Override
3724     public void resetSizeCounter() {
3725       startOffset = (int) (totalBytesRead + currentByteBufferPos - currentByteBufferStartPos);
3726     }
3727
3728     @Override
3729     public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
3730       if (byteLimit < 0) {
3731         throw InvalidProtocolBufferException.negativeSize();
3732       }
3733       byteLimit += getTotalBytesRead();
3734       final int oldLimit = currentLimit;
3735       if (byteLimit > oldLimit) {
3736         throw InvalidProtocolBufferException.truncatedMessage();
3737       }
3738       currentLimit = byteLimit;
3739
3740       recomputeBufferSizeAfterLimit();
3741
3742       return oldLimit;
3743     }
3744
3745     private void recomputeBufferSizeAfterLimit() {
3746       totalBufferSize += bufferSizeAfterCurrentLimit;
3747       final int bufferEnd = totalBufferSize - startOffset;
3748       if (bufferEnd > currentLimit) {
3749         // Limit is in current buffer.
3750         bufferSizeAfterCurrentLimit = bufferEnd - currentLimit;
3751         totalBufferSize -= bufferSizeAfterCurrentLimit;
3752       } else {
3753         bufferSizeAfterCurrentLimit = 0;
3754       }
3755     }
3756
3757     @Override
3758     public void popLimit(final int oldLimit) {
3759       currentLimit = oldLimit;
3760       recomputeBufferSizeAfterLimit();
3761     }
3762
3763     @Override
3764     public int getBytesUntilLimit() {
3765       if (currentLimit == Integer.MAX_VALUE) {
3766         return -1;
3767       }
3768
3769       return currentLimit - getTotalBytesRead();
3770     }
3771
3772     @Override
3773     public boolean isAtEnd() throws IOException {
3774       return totalBytesRead + currentByteBufferPos - currentByteBufferStartPos == totalBufferSize;
3775     }
3776
3777     @Override
3778     public int getTotalBytesRead() {
3779       return (int)
3780           (totalBytesRead - startOffset + currentByteBufferPos - currentByteBufferStartPos);
3781     }
3782
3783     @Override
3784     public byte readRawByte() throws IOException {
3785       if (currentRemaining() == 0) {
3786         getNextByteBuffer();
3787       }
3788       return UnsafeUtil.getByte(currentByteBufferPos++);
3789     }
3790
3791     @Override
3792     public byte[] readRawBytes(final int length) throws IOException {
3793       if (length >= 0 && length <= currentRemaining()) {
3794         byte[] bytes = new byte[length];
3795         UnsafeUtil.copyMemory(currentByteBufferPos, bytes, 0, length);
3796         currentByteBufferPos += length;
3797         return bytes;
3798       }
3799       if (length >= 0 && length <= remaining()) {
3800         byte[] bytes = new byte[length];
3801         readRawBytesTo(bytes, 0, length);
3802         return bytes;
3803       }
3804
3805       if (length <= 0) {
3806         if (length == 0) {
3807           return EMPTY_BYTE_ARRAY;
3808         } else {
3809           throw InvalidProtocolBufferException.negativeSize();
3810         }
3811       }
3812
3813       throw InvalidProtocolBufferException.truncatedMessage();
3814     }
3815
3816     /**
3817      * Try to get raw bytes from {@code input} with the size of {@code length} and copy to {@code
3818      * bytes} array. If the size is bigger than the number of remaining bytes in the input, then
3819      * throw {@code truncatedMessage} exception.
3820      *
3821      * @param bytes
3822      * @param offset
3823      * @param length
3824      * @throws IOException
3825      */
3826     private void readRawBytesTo(byte[] bytes, int offset, final int length) throws IOException {
3827       if (length >= 0 && length <= remaining()) {
3828         int l = length;
3829         while (l > 0) {
3830           if (currentRemaining() == 0) {
3831             getNextByteBuffer();
3832           }
3833           int bytesToCopy = Math.min(l, (int) currentRemaining());
3834           UnsafeUtil.copyMemory(currentByteBufferPos, bytes, length - l + offset, bytesToCopy);
3835           l -= bytesToCopy;
3836           currentByteBufferPos += bytesToCopy;
3837         }
3838         return;
3839       }
3840
3841       if (length <= 0) {
3842         if (length == 0) {
3843           return;
3844         } else {
3845           throw InvalidProtocolBufferException.negativeSize();
3846         }
3847       }
3848       throw InvalidProtocolBufferException.truncatedMessage();
3849     }
3850
3851     @Override
3852     public void skipRawBytes(final int length) throws IOException {
3853       if (length >= 0
3854           && length
3855               <= (totalBufferSize
3856                   - totalBytesRead
3857                   - currentByteBufferPos
3858                   + currentByteBufferStartPos)) {
3859         // We have all the bytes we need already.
3860         int l = length;
3861         while (l > 0) {
3862           if (currentRemaining() == 0) {
3863             getNextByteBuffer();
3864           }
3865           int rl = Math.min(l, (int) currentRemaining());
3866           l -= rl;
3867           currentByteBufferPos += rl;
3868         }
3869         return;
3870       }
3871
3872       if (length < 0) {
3873         throw InvalidProtocolBufferException.negativeSize();
3874       }
3875       throw InvalidProtocolBufferException.truncatedMessage();
3876     }
3877
3878     // TODO: optimize to fastpath
3879     private void skipRawVarint() throws IOException {
3880       for (int i = 0; i < MAX_VARINT_SIZE; i++) {
3881         if (readRawByte() >= 0) {
3882           return;
3883         }
3884       }
3885       throw InvalidProtocolBufferException.malformedVarint();
3886     }
3887
3888     /**
3889      * Try to get the number of remaining bytes in {@code input}.
3890      *
3891      * @return the number of remaining bytes in {@code input}.
3892      */
3893     private int remaining() {
3894       return (int)
3895           (totalBufferSize - totalBytesRead - currentByteBufferPos + currentByteBufferStartPos);
3896     }
3897
3898     /**
3899      * Try to get the number of remaining bytes in {@code currentByteBuffer}.
3900      *
3901      * @return the number of remaining bytes in {@code currentByteBuffer}
3902      */
3903     private long currentRemaining() {
3904       return (currentByteBufferLimit - currentByteBufferPos);
3905     }
3906
3907     private ByteBuffer slice(int begin, int end) throws IOException {
3908       int prevPos = currentByteBuffer.position();
3909       int prevLimit = currentByteBuffer.limit();
3910       try {
3911         currentByteBuffer.position(begin);
3912         currentByteBuffer.limit(end);
3913         return currentByteBuffer.slice();
3914       } catch (IllegalArgumentException e) {
3915         throw InvalidProtocolBufferException.truncatedMessage();
3916       } finally {
3917         currentByteBuffer.position(prevPos);
3918         currentByteBuffer.limit(prevLimit);
3919       }
3920     }
3921   }
3922 }