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