• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 package com.google.protobuf;
32 
33 import static com.google.protobuf.WireFormat.FIXED32_SIZE;
34 import static com.google.protobuf.WireFormat.FIXED64_SIZE;
35 import static com.google.protobuf.WireFormat.WIRETYPE_END_GROUP;
36 import static com.google.protobuf.WireFormat.WIRETYPE_FIXED32;
37 import static com.google.protobuf.WireFormat.WIRETYPE_FIXED64;
38 import static com.google.protobuf.WireFormat.WIRETYPE_LENGTH_DELIMITED;
39 import static com.google.protobuf.WireFormat.WIRETYPE_START_GROUP;
40 import static com.google.protobuf.WireFormat.WIRETYPE_VARINT;
41 
42 import java.io.IOException;
43 import java.nio.ByteBuffer;
44 import java.util.List;
45 import java.util.Map;
46 
47 /**
48  * A {@link Reader} that reads from a buffer containing a message serialized with the binary
49  * protocol.
50  */
51 @ExperimentalApi
52 abstract class BinaryReader implements Reader {
53   private static final int FIXED32_MULTIPLE_MASK = FIXED32_SIZE - 1;
54   private static final int FIXED64_MULTIPLE_MASK = FIXED64_SIZE - 1;
55 
56   /**
57    * Creates a new reader using the given {@code buffer} as input.
58    *
59    * @param buffer the input buffer. The buffer (including position, limit, etc.) will not be
60    *     modified. To increment the buffer position after the read completes, use the value returned
61    *     by {@link #getTotalBytesRead()}.
62    * @param bufferIsImmutable if {@code true} the reader assumes that the content of {@code buffer}
63    *     will never change and any allocated {@link ByteString} instances will by directly wrap
64    *     slices of {@code buffer}.
65    * @return the reader
66    */
newInstance(ByteBuffer buffer, boolean bufferIsImmutable)67   public static BinaryReader newInstance(ByteBuffer buffer, boolean bufferIsImmutable) {
68     if (buffer.hasArray()) {
69       // TODO(nathanmittler): Add support for unsafe operations.
70       return new SafeHeapReader(buffer, bufferIsImmutable);
71     }
72     // TODO(nathanmittler): Add support for direct buffers
73     throw new IllegalArgumentException("Direct buffers not yet supported");
74   }
75 
76   /** Only allow subclassing for inner classes. */
BinaryReader()77   private BinaryReader() {}
78 
79   /** Returns the total number of bytes read so far from the input buffer. */
getTotalBytesRead()80   public abstract int getTotalBytesRead();
81 
82   @Override
shouldDiscardUnknownFields()83   public boolean shouldDiscardUnknownFields() {
84     return false;
85   }
86 
87   /**
88    * A {@link BinaryReader} implementation that operates on a heap {@link ByteBuffer}. Uses only
89    * safe operations on the underlying array.
90    */
91   private static final class SafeHeapReader extends BinaryReader {
92     private final boolean bufferIsImmutable;
93     private final byte[] buffer;
94     private int pos;
95     private final int initialPos;
96     private int limit;
97     private int tag;
98     private int endGroupTag;
99 
SafeHeapReader(ByteBuffer bytebuf, boolean bufferIsImmutable)100     public SafeHeapReader(ByteBuffer bytebuf, boolean bufferIsImmutable) {
101       this.bufferIsImmutable = bufferIsImmutable;
102       buffer = bytebuf.array();
103       initialPos = pos = bytebuf.arrayOffset() + bytebuf.position();
104       limit = bytebuf.arrayOffset() + bytebuf.limit();
105     }
106 
isAtEnd()107     private boolean isAtEnd() {
108       return pos == limit;
109     }
110 
111     @Override
getTotalBytesRead()112     public int getTotalBytesRead() {
113       return pos - initialPos;
114     }
115 
116     @Override
getFieldNumber()117     public int getFieldNumber() throws IOException {
118       if (isAtEnd()) {
119         return Reader.READ_DONE;
120       }
121       tag = readVarint32();
122       if (tag == endGroupTag) {
123         return Reader.READ_DONE;
124       }
125       return WireFormat.getTagFieldNumber(tag);
126     }
127 
128     @Override
getTag()129     public int getTag() {
130       return tag;
131     }
132 
133     @Override
skipField()134     public boolean skipField() throws IOException {
135       if (isAtEnd() || tag == endGroupTag) {
136         return false;
137       }
138 
139       switch (WireFormat.getTagWireType(tag)) {
140         case WIRETYPE_VARINT:
141           skipVarint();
142           return true;
143         case WIRETYPE_FIXED64:
144           skipBytes(FIXED64_SIZE);
145           return true;
146         case WIRETYPE_LENGTH_DELIMITED:
147           skipBytes(readVarint32());
148           return true;
149         case WIRETYPE_FIXED32:
150           skipBytes(FIXED32_SIZE);
151           return true;
152         case WIRETYPE_START_GROUP:
153           skipGroup();
154           return true;
155         default:
156           throw InvalidProtocolBufferException.invalidWireType();
157       }
158     }
159 
160     @Override
readDouble()161     public double readDouble() throws IOException {
162       requireWireType(WIRETYPE_FIXED64);
163       return Double.longBitsToDouble(readLittleEndian64());
164     }
165 
166     @Override
readFloat()167     public float readFloat() throws IOException {
168       requireWireType(WIRETYPE_FIXED32);
169       return Float.intBitsToFloat(readLittleEndian32());
170     }
171 
172     @Override
readUInt64()173     public long readUInt64() throws IOException {
174       requireWireType(WIRETYPE_VARINT);
175       return readVarint64();
176     }
177 
178     @Override
readInt64()179     public long readInt64() throws IOException {
180       requireWireType(WIRETYPE_VARINT);
181       return readVarint64();
182     }
183 
184     @Override
readInt32()185     public int readInt32() throws IOException {
186       requireWireType(WIRETYPE_VARINT);
187       return readVarint32();
188     }
189 
190     @Override
readFixed64()191     public long readFixed64() throws IOException {
192       requireWireType(WIRETYPE_FIXED64);
193       return readLittleEndian64();
194     }
195 
196     @Override
readFixed32()197     public int readFixed32() throws IOException {
198       requireWireType(WIRETYPE_FIXED32);
199       return readLittleEndian32();
200     }
201 
202     @Override
readBool()203     public boolean readBool() throws IOException {
204       requireWireType(WIRETYPE_VARINT);
205       return readVarint32() != 0;
206     }
207 
208     @Override
readString()209     public String readString() throws IOException {
210       return readStringInternal(false);
211     }
212 
213     @Override
readStringRequireUtf8()214     public String readStringRequireUtf8() throws IOException {
215       return readStringInternal(true);
216     }
217 
readStringInternal(boolean requireUtf8)218     public String readStringInternal(boolean requireUtf8) throws IOException {
219       requireWireType(WIRETYPE_LENGTH_DELIMITED);
220       final int size = readVarint32();
221       if (size == 0) {
222         return "";
223       }
224 
225       requireBytes(size);
226       if (requireUtf8 && !Utf8.isValidUtf8(buffer, pos, pos + size)) {
227         throw InvalidProtocolBufferException.invalidUtf8();
228       }
229       String result = new String(buffer, pos, size, Internal.UTF_8);
230       pos += size;
231       return result;
232     }
233 
234     @Override
readMessage(Class<T> clazz, ExtensionRegistryLite extensionRegistry)235     public <T> T readMessage(Class<T> clazz, ExtensionRegistryLite extensionRegistry)
236         throws IOException {
237       requireWireType(WIRETYPE_LENGTH_DELIMITED);
238       return readMessage(Protobuf.getInstance().schemaFor(clazz), extensionRegistry);
239     }
240 
241     @Override
readMessageBySchemaWithCheck( Schema<T> schema, ExtensionRegistryLite extensionRegistry)242     public <T> T readMessageBySchemaWithCheck(
243         Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException {
244       requireWireType(WIRETYPE_LENGTH_DELIMITED);
245       return readMessage(schema, extensionRegistry);
246     }
247 
readMessage(Schema<T> schema, ExtensionRegistryLite extensionRegistry)248     private <T> T readMessage(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
249         throws IOException {
250       int size = readVarint32();
251       requireBytes(size);
252 
253       // Update the limit.
254       int prevLimit = limit;
255       int newLimit = pos + size;
256       limit = newLimit;
257 
258       try {
259         // Allocate and read the message.
260         T message = schema.newInstance();
261         schema.mergeFrom(message, this, extensionRegistry);
262         schema.makeImmutable(message);
263 
264         if (pos != newLimit) {
265           throw InvalidProtocolBufferException.parseFailure();
266         }
267         return message;
268       } finally {
269         // Restore the limit.
270         limit = prevLimit;
271       }
272     }
273 
274     @Override
readGroup(Class<T> clazz, ExtensionRegistryLite extensionRegistry)275     public <T> T readGroup(Class<T> clazz, ExtensionRegistryLite extensionRegistry)
276         throws IOException {
277       requireWireType(WIRETYPE_START_GROUP);
278       return readGroup(Protobuf.getInstance().schemaFor(clazz), extensionRegistry);
279     }
280 
281     @Override
readGroupBySchemaWithCheck( Schema<T> schema, ExtensionRegistryLite extensionRegistry)282     public <T> T readGroupBySchemaWithCheck(
283         Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException {
284       requireWireType(WIRETYPE_START_GROUP);
285       return readGroup(schema, extensionRegistry);
286     }
287 
readGroup(Schema<T> schema, ExtensionRegistryLite extensionRegistry)288     private <T> T readGroup(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
289         throws IOException {
290       int prevEndGroupTag = endGroupTag;
291       endGroupTag = WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WIRETYPE_END_GROUP);
292 
293       try {
294         // Allocate and read the message.
295         T message = schema.newInstance();
296         schema.mergeFrom(message, this, extensionRegistry);
297         schema.makeImmutable(message);
298 
299         if (tag != endGroupTag) {
300           throw InvalidProtocolBufferException.parseFailure();
301         }
302         return message;
303       } finally {
304         // Restore the old end group tag.
305         endGroupTag = prevEndGroupTag;
306       }
307     }
308 
309     @Override
readBytes()310     public ByteString readBytes() throws IOException {
311       requireWireType(WIRETYPE_LENGTH_DELIMITED);
312       int size = readVarint32();
313       if (size == 0) {
314         return ByteString.EMPTY;
315       }
316 
317       requireBytes(size);
318       ByteString bytes =
319           bufferIsImmutable
320               ? ByteString.wrap(buffer, pos, size)
321               : ByteString.copyFrom(buffer, pos, size);
322       pos += size;
323       return bytes;
324     }
325 
326     @Override
readUInt32()327     public int readUInt32() throws IOException {
328       requireWireType(WIRETYPE_VARINT);
329       return readVarint32();
330     }
331 
332     @Override
readEnum()333     public int readEnum() throws IOException {
334       requireWireType(WIRETYPE_VARINT);
335       return readVarint32();
336     }
337 
338     @Override
readSFixed32()339     public int readSFixed32() throws IOException {
340       requireWireType(WIRETYPE_FIXED32);
341       return readLittleEndian32();
342     }
343 
344     @Override
readSFixed64()345     public long readSFixed64() throws IOException {
346       requireWireType(WIRETYPE_FIXED64);
347       return readLittleEndian64();
348     }
349 
350     @Override
readSInt32()351     public int readSInt32() throws IOException {
352       requireWireType(WIRETYPE_VARINT);
353       return CodedInputStream.decodeZigZag32(readVarint32());
354     }
355 
356     @Override
readSInt64()357     public long readSInt64() throws IOException {
358       requireWireType(WIRETYPE_VARINT);
359       return CodedInputStream.decodeZigZag64(readVarint64());
360     }
361 
362     @Override
readDoubleList(List<Double> target)363     public void readDoubleList(List<Double> target) throws IOException {
364       if (target instanceof DoubleArrayList) {
365         DoubleArrayList plist = (DoubleArrayList) target;
366         switch (WireFormat.getTagWireType(tag)) {
367           case WIRETYPE_LENGTH_DELIMITED:
368             final int bytes = readVarint32();
369             verifyPackedFixed64Length(bytes);
370             final int fieldEndPos = pos + bytes;
371             while (pos < fieldEndPos) {
372               plist.addDouble(Double.longBitsToDouble(readLittleEndian64_NoCheck()));
373             }
374             break;
375           case WIRETYPE_FIXED64:
376             while (true) {
377               plist.addDouble(readDouble());
378 
379               if (isAtEnd()) {
380                 return;
381               }
382               int prevPos = pos;
383               int nextTag = readVarint32();
384               if (nextTag != tag) {
385                 // We've reached the end of the repeated field. Rewind the buffer position to before
386                 // the new tag.
387                 pos = prevPos;
388                 return;
389               }
390             }
391           default:
392             throw InvalidProtocolBufferException.invalidWireType();
393         }
394       } else {
395         switch (WireFormat.getTagWireType(tag)) {
396           case WIRETYPE_LENGTH_DELIMITED:
397             final int bytes = readVarint32();
398             verifyPackedFixed64Length(bytes);
399             final int fieldEndPos = pos + bytes;
400             while (pos < fieldEndPos) {
401               target.add(Double.longBitsToDouble(readLittleEndian64_NoCheck()));
402             }
403             break;
404           case WIRETYPE_FIXED64:
405             while (true) {
406               target.add(readDouble());
407 
408               if (isAtEnd()) {
409                 return;
410               }
411               int prevPos = pos;
412               int nextTag = readVarint32();
413               if (nextTag != tag) {
414                 // We've reached the end of the repeated field. Rewind the buffer position to before
415                 // the new tag.
416                 pos = prevPos;
417                 return;
418               }
419             }
420           default:
421             throw InvalidProtocolBufferException.invalidWireType();
422         }
423       }
424     }
425 
426     @Override
readFloatList(List<Float> target)427     public void readFloatList(List<Float> target) throws IOException {
428       if (target instanceof FloatArrayList) {
429         FloatArrayList plist = (FloatArrayList) target;
430         switch (WireFormat.getTagWireType(tag)) {
431           case WIRETYPE_LENGTH_DELIMITED:
432             final int bytes = readVarint32();
433             verifyPackedFixed32Length(bytes);
434             final int fieldEndPos = pos + bytes;
435             while (pos < fieldEndPos) {
436               plist.addFloat(Float.intBitsToFloat(readLittleEndian32_NoCheck()));
437             }
438             break;
439           case WIRETYPE_FIXED32:
440             while (true) {
441               plist.addFloat(readFloat());
442 
443               if (isAtEnd()) {
444                 return;
445               }
446               int prevPos = pos;
447               int nextTag = readVarint32();
448               if (nextTag != tag) {
449                 // We've reached the end of the repeated field. Rewind the buffer position to before
450                 // the new tag.
451                 pos = prevPos;
452                 return;
453               }
454             }
455           default:
456             throw InvalidProtocolBufferException.invalidWireType();
457         }
458       } else {
459         switch (WireFormat.getTagWireType(tag)) {
460           case WIRETYPE_LENGTH_DELIMITED:
461             final int bytes = readVarint32();
462             verifyPackedFixed32Length(bytes);
463             final int fieldEndPos = pos + bytes;
464             while (pos < fieldEndPos) {
465               target.add(Float.intBitsToFloat(readLittleEndian32_NoCheck()));
466             }
467             break;
468           case WIRETYPE_FIXED32:
469             while (true) {
470               target.add(readFloat());
471 
472               if (isAtEnd()) {
473                 return;
474               }
475               int prevPos = pos;
476               int nextTag = readVarint32();
477               if (nextTag != tag) {
478                 // We've reached the end of the repeated field. Rewind the buffer position to before
479                 // the new tag.
480                 pos = prevPos;
481                 return;
482               }
483             }
484           default:
485             throw InvalidProtocolBufferException.invalidWireType();
486         }
487       }
488     }
489 
490     @Override
readUInt64List(List<Long> target)491     public void readUInt64List(List<Long> target) throws IOException {
492       if (target instanceof LongArrayList) {
493         LongArrayList plist = (LongArrayList) target;
494         switch (WireFormat.getTagWireType(tag)) {
495           case WIRETYPE_LENGTH_DELIMITED:
496             final int bytes = readVarint32();
497             final int fieldEndPos = pos + bytes;
498             while (pos < fieldEndPos) {
499               plist.addLong(readVarint64());
500             }
501             requirePosition(fieldEndPos);
502             break;
503           case WIRETYPE_VARINT:
504             while (true) {
505               plist.addLong(readUInt64());
506 
507               if (isAtEnd()) {
508                 return;
509               }
510               int prevPos = pos;
511               int nextTag = readVarint32();
512               if (nextTag != tag) {
513                 // We've reached the end of the repeated field. Rewind the buffer position to before
514                 // the new tag.
515                 pos = prevPos;
516                 return;
517               }
518             }
519           default:
520             throw InvalidProtocolBufferException.invalidWireType();
521         }
522       } else {
523         switch (WireFormat.getTagWireType(tag)) {
524           case WIRETYPE_LENGTH_DELIMITED:
525             final int bytes = readVarint32();
526             final int fieldEndPos = pos + bytes;
527             while (pos < fieldEndPos) {
528               target.add(readVarint64());
529             }
530             requirePosition(fieldEndPos);
531             break;
532           case WIRETYPE_VARINT:
533             while (true) {
534               target.add(readUInt64());
535 
536               if (isAtEnd()) {
537                 return;
538               }
539               int prevPos = pos;
540               int nextTag = readVarint32();
541               if (nextTag != tag) {
542                 // We've reached the end of the repeated field. Rewind the buffer position to before
543                 // the new tag.
544                 pos = prevPos;
545                 return;
546               }
547             }
548           default:
549             throw InvalidProtocolBufferException.invalidWireType();
550         }
551       }
552     }
553 
554     @Override
readInt64List(List<Long> target)555     public void readInt64List(List<Long> target) throws IOException {
556       if (target instanceof LongArrayList) {
557         LongArrayList plist = (LongArrayList) target;
558         switch (WireFormat.getTagWireType(tag)) {
559           case WIRETYPE_LENGTH_DELIMITED:
560             final int bytes = readVarint32();
561             final int fieldEndPos = pos + bytes;
562             while (pos < fieldEndPos) {
563               plist.addLong(readVarint64());
564             }
565             requirePosition(fieldEndPos);
566             break;
567           case WIRETYPE_VARINT:
568             while (true) {
569               plist.addLong(readInt64());
570 
571               if (isAtEnd()) {
572                 return;
573               }
574               int prevPos = pos;
575               int nextTag = readVarint32();
576               if (nextTag != tag) {
577                 // We've reached the end of the repeated field. Rewind the buffer position to before
578                 // the new tag.
579                 pos = prevPos;
580                 return;
581               }
582             }
583           default:
584             throw InvalidProtocolBufferException.invalidWireType();
585         }
586       } else {
587         switch (WireFormat.getTagWireType(tag)) {
588           case WIRETYPE_LENGTH_DELIMITED:
589             final int bytes = readVarint32();
590             final int fieldEndPos = pos + bytes;
591             while (pos < fieldEndPos) {
592               target.add(readVarint64());
593             }
594             requirePosition(fieldEndPos);
595             break;
596           case WIRETYPE_VARINT:
597             while (true) {
598               target.add(readInt64());
599 
600               if (isAtEnd()) {
601                 return;
602               }
603               int prevPos = pos;
604               int nextTag = readVarint32();
605               if (nextTag != tag) {
606                 // We've reached the end of the repeated field. Rewind the buffer position to before
607                 // the new tag.
608                 pos = prevPos;
609                 return;
610               }
611             }
612           default:
613             throw InvalidProtocolBufferException.invalidWireType();
614         }
615       }
616     }
617 
618     @Override
readInt32List(List<Integer> target)619     public void readInt32List(List<Integer> target) throws IOException {
620       if (target instanceof IntArrayList) {
621         IntArrayList plist = (IntArrayList) target;
622         switch (WireFormat.getTagWireType(tag)) {
623           case WIRETYPE_LENGTH_DELIMITED:
624             final int bytes = readVarint32();
625             final int fieldEndPos = pos + bytes;
626             while (pos < fieldEndPos) {
627               plist.addInt(readVarint32());
628             }
629             requirePosition(fieldEndPos);
630             break;
631           case WIRETYPE_VARINT:
632             while (true) {
633               plist.addInt(readInt32());
634 
635               if (isAtEnd()) {
636                 return;
637               }
638               int prevPos = pos;
639               int nextTag = readVarint32();
640               if (nextTag != tag) {
641                 // We've reached the end of the repeated field. Rewind the buffer position to before
642                 // the new tag.
643                 pos = prevPos;
644                 return;
645               }
646             }
647           default:
648             throw InvalidProtocolBufferException.invalidWireType();
649         }
650       } else {
651         switch (WireFormat.getTagWireType(tag)) {
652           case WIRETYPE_LENGTH_DELIMITED:
653             final int bytes = readVarint32();
654             final int fieldEndPos = pos + bytes;
655             while (pos < fieldEndPos) {
656               target.add(readVarint32());
657             }
658             requirePosition(fieldEndPos);
659             break;
660           case WIRETYPE_VARINT:
661             while (true) {
662               target.add(readInt32());
663 
664               if (isAtEnd()) {
665                 return;
666               }
667               int prevPos = pos;
668               int nextTag = readVarint32();
669               if (nextTag != tag) {
670                 // We've reached the end of the repeated field. Rewind the buffer position to before
671                 // the new tag.
672                 pos = prevPos;
673                 return;
674               }
675             }
676           default:
677             throw InvalidProtocolBufferException.invalidWireType();
678         }
679       }
680     }
681 
682     @Override
readFixed64List(List<Long> target)683     public void readFixed64List(List<Long> target) throws IOException {
684       if (target instanceof LongArrayList) {
685         LongArrayList plist = (LongArrayList) target;
686         switch (WireFormat.getTagWireType(tag)) {
687           case WIRETYPE_LENGTH_DELIMITED:
688             final int bytes = readVarint32();
689             verifyPackedFixed64Length(bytes);
690             final int fieldEndPos = pos + bytes;
691             while (pos < fieldEndPos) {
692               plist.addLong(readLittleEndian64_NoCheck());
693             }
694             break;
695           case WIRETYPE_FIXED64:
696             while (true) {
697               plist.addLong(readFixed64());
698 
699               if (isAtEnd()) {
700                 return;
701               }
702               int prevPos = pos;
703               int nextTag = readVarint32();
704               if (nextTag != tag) {
705                 // We've reached the end of the repeated field. Rewind the buffer position to before
706                 // the new tag.
707                 pos = prevPos;
708                 return;
709               }
710             }
711           default:
712             throw InvalidProtocolBufferException.invalidWireType();
713         }
714       } else {
715         switch (WireFormat.getTagWireType(tag)) {
716           case WIRETYPE_LENGTH_DELIMITED:
717             final int bytes = readVarint32();
718             verifyPackedFixed64Length(bytes);
719             final int fieldEndPos = pos + bytes;
720             while (pos < fieldEndPos) {
721               target.add(readLittleEndian64_NoCheck());
722             }
723             break;
724           case WIRETYPE_FIXED64:
725             while (true) {
726               target.add(readFixed64());
727 
728               if (isAtEnd()) {
729                 return;
730               }
731               int prevPos = pos;
732               int nextTag = readVarint32();
733               if (nextTag != tag) {
734                 // We've reached the end of the repeated field. Rewind the buffer position to before
735                 // the new tag.
736                 pos = prevPos;
737                 return;
738               }
739             }
740           default:
741             throw InvalidProtocolBufferException.invalidWireType();
742         }
743       }
744     }
745 
746     @Override
readFixed32List(List<Integer> target)747     public void readFixed32List(List<Integer> target) throws IOException {
748       if (target instanceof IntArrayList) {
749         IntArrayList plist = (IntArrayList) target;
750         switch (WireFormat.getTagWireType(tag)) {
751           case WIRETYPE_LENGTH_DELIMITED:
752             final int bytes = readVarint32();
753             verifyPackedFixed32Length(bytes);
754             final int fieldEndPos = pos + bytes;
755             while (pos < fieldEndPos) {
756               plist.addInt(readLittleEndian32_NoCheck());
757             }
758             break;
759           case WIRETYPE_FIXED32:
760             while (true) {
761               plist.addInt(readFixed32());
762 
763               if (isAtEnd()) {
764                 return;
765               }
766               int prevPos = pos;
767               int nextTag = readVarint32();
768               if (nextTag != tag) {
769                 // We've reached the end of the repeated field. Rewind the buffer position to before
770                 // the new tag.
771                 pos = prevPos;
772                 return;
773               }
774             }
775           default:
776             throw InvalidProtocolBufferException.invalidWireType();
777         }
778       } else {
779         switch (WireFormat.getTagWireType(tag)) {
780           case WIRETYPE_LENGTH_DELIMITED:
781             final int bytes = readVarint32();
782             verifyPackedFixed32Length(bytes);
783             final int fieldEndPos = pos + bytes;
784             while (pos < fieldEndPos) {
785               target.add(readLittleEndian32_NoCheck());
786             }
787             break;
788           case WIRETYPE_FIXED32:
789             while (true) {
790               target.add(readFixed32());
791 
792               if (isAtEnd()) {
793                 return;
794               }
795               int prevPos = pos;
796               int nextTag = readVarint32();
797               if (nextTag != tag) {
798                 // We've reached the end of the repeated field. Rewind the buffer position to before
799                 // the new tag.
800                 pos = prevPos;
801                 return;
802               }
803             }
804           default:
805             throw InvalidProtocolBufferException.invalidWireType();
806         }
807       }
808     }
809 
810     @Override
readBoolList(List<Boolean> target)811     public void readBoolList(List<Boolean> target) throws IOException {
812       if (target instanceof BooleanArrayList) {
813         BooleanArrayList plist = (BooleanArrayList) target;
814         switch (WireFormat.getTagWireType(tag)) {
815           case WIRETYPE_LENGTH_DELIMITED:
816             final int bytes = readVarint32();
817             final int fieldEndPos = pos + bytes;
818             while (pos < fieldEndPos) {
819               plist.addBoolean(readVarint32() != 0);
820             }
821             requirePosition(fieldEndPos);
822             break;
823           case WIRETYPE_VARINT:
824             while (true) {
825               plist.addBoolean(readBool());
826 
827               if (isAtEnd()) {
828                 return;
829               }
830               int prevPos = pos;
831               int nextTag = readVarint32();
832               if (nextTag != tag) {
833                 // We've reached the end of the repeated field. Rewind the buffer position to before
834                 // the new tag.
835                 pos = prevPos;
836                 return;
837               }
838             }
839           default:
840             throw InvalidProtocolBufferException.invalidWireType();
841         }
842       } else {
843         switch (WireFormat.getTagWireType(tag)) {
844           case WIRETYPE_LENGTH_DELIMITED:
845             final int bytes = readVarint32();
846             final int fieldEndPos = pos + bytes;
847             while (pos < fieldEndPos) {
848               target.add(readVarint32() != 0);
849             }
850             requirePosition(fieldEndPos);
851             break;
852           case WIRETYPE_VARINT:
853             while (true) {
854               target.add(readBool());
855 
856               if (isAtEnd()) {
857                 return;
858               }
859               int prevPos = pos;
860               int nextTag = readVarint32();
861               if (nextTag != tag) {
862                 // We've reached the end of the repeated field. Rewind the buffer position to before
863                 // the new tag.
864                 pos = prevPos;
865                 return;
866               }
867             }
868           default:
869             throw InvalidProtocolBufferException.invalidWireType();
870         }
871       }
872     }
873 
874     @Override
readStringList(List<String> target)875     public void readStringList(List<String> target) throws IOException {
876       readStringListInternal(target, false);
877     }
878 
879     @Override
readStringListRequireUtf8(List<String> target)880     public void readStringListRequireUtf8(List<String> target) throws IOException {
881       readStringListInternal(target, true);
882     }
883 
readStringListInternal(List<String> target, boolean requireUtf8)884     public void readStringListInternal(List<String> target, boolean requireUtf8)
885         throws IOException {
886       if (WireFormat.getTagWireType(tag) != WIRETYPE_LENGTH_DELIMITED) {
887         throw InvalidProtocolBufferException.invalidWireType();
888       }
889 
890       if (target instanceof LazyStringList && !requireUtf8) {
891         LazyStringList lazyList = (LazyStringList) target;
892         while (true) {
893           lazyList.add(readBytes());
894 
895           if (isAtEnd()) {
896             return;
897           }
898           int prevPos = pos;
899           int nextTag = readVarint32();
900           if (nextTag != tag) {
901             // We've reached the end of the repeated field. Rewind the buffer position to before
902             // the new tag.
903             pos = prevPos;
904             return;
905           }
906         }
907       } else {
908         while (true) {
909           target.add(readStringInternal(requireUtf8));
910 
911           if (isAtEnd()) {
912             return;
913           }
914           int prevPos = pos;
915           int nextTag = readVarint32();
916           if (nextTag != tag) {
917             // We've reached the end of the repeated field. Rewind the buffer position to before
918             // the new tag.
919             pos = prevPos;
920             return;
921           }
922         }
923       }
924     }
925 
926     @Override
readMessageList( List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry)927     public <T> void readMessageList(
928         List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry)
929         throws IOException {
930       final Schema<T> schema = Protobuf.getInstance().schemaFor(targetType);
931       readMessageList(target, schema, extensionRegistry);
932     }
933 
934     @Override
readMessageList( List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)935     public <T> void readMessageList(
936         List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)
937         throws IOException {
938       if (WireFormat.getTagWireType(tag) != WIRETYPE_LENGTH_DELIMITED) {
939         throw InvalidProtocolBufferException.invalidWireType();
940       }
941       final int listTag = tag;
942       while (true) {
943         target.add(readMessage(schema, extensionRegistry));
944 
945         if (isAtEnd()) {
946           return;
947         }
948         int prevPos = pos;
949         int nextTag = readVarint32();
950         if (nextTag != listTag) {
951           // We've reached the end of the repeated field. Rewind the buffer position to before
952           // the new tag.
953           pos = prevPos;
954           return;
955         }
956       }
957     }
958 
959     @Override
readGroupList( List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry)960     public <T> void readGroupList(
961         List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry)
962         throws IOException {
963       final Schema<T> schema = Protobuf.getInstance().schemaFor(targetType);
964       readGroupList(target, schema, extensionRegistry);
965     }
966 
967     @Override
readGroupList( List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)968     public <T> void readGroupList(
969         List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)
970         throws IOException {
971       if (WireFormat.getTagWireType(tag) != WIRETYPE_START_GROUP) {
972         throw InvalidProtocolBufferException.invalidWireType();
973       }
974       final int listTag = tag;
975       while (true) {
976         target.add(readGroup(schema, extensionRegistry));
977 
978         if (isAtEnd()) {
979           return;
980         }
981         int prevPos = pos;
982         int nextTag = readVarint32();
983         if (nextTag != listTag) {
984           // We've reached the end of the repeated field. Rewind the buffer position to before
985           // the new tag.
986           pos = prevPos;
987           return;
988         }
989       }
990     }
991 
992     @Override
readBytesList(List<ByteString> target)993     public void readBytesList(List<ByteString> target) throws IOException {
994       if (WireFormat.getTagWireType(tag) != WIRETYPE_LENGTH_DELIMITED) {
995         throw InvalidProtocolBufferException.invalidWireType();
996       }
997 
998       while (true) {
999         target.add(readBytes());
1000 
1001         if (isAtEnd()) {
1002           return;
1003         }
1004         int prevPos = pos;
1005         int nextTag = readVarint32();
1006         if (nextTag != tag) {
1007           // We've reached the end of the repeated field. Rewind the buffer position to before
1008           // the new tag.
1009           pos = prevPos;
1010           return;
1011         }
1012       }
1013     }
1014 
1015     @Override
readUInt32List(List<Integer> target)1016     public void readUInt32List(List<Integer> target) throws IOException {
1017       if (target instanceof IntArrayList) {
1018         IntArrayList plist = (IntArrayList) target;
1019         switch (WireFormat.getTagWireType(tag)) {
1020           case WIRETYPE_LENGTH_DELIMITED:
1021             final int bytes = readVarint32();
1022             final int fieldEndPos = pos + bytes;
1023             while (pos < fieldEndPos) {
1024               plist.addInt(readVarint32());
1025             }
1026             break;
1027           case WIRETYPE_VARINT:
1028             while (true) {
1029               plist.addInt(readUInt32());
1030 
1031               if (isAtEnd()) {
1032                 return;
1033               }
1034               int prevPos = pos;
1035               int nextTag = readVarint32();
1036               if (nextTag != tag) {
1037                 // We've reached the end of the repeated field. Rewind the buffer position to before
1038                 // the new tag.
1039                 pos = prevPos;
1040                 return;
1041               }
1042             }
1043           default:
1044             throw InvalidProtocolBufferException.invalidWireType();
1045         }
1046       } else {
1047         switch (WireFormat.getTagWireType(tag)) {
1048           case WIRETYPE_LENGTH_DELIMITED:
1049             final int bytes = readVarint32();
1050             final int fieldEndPos = pos + bytes;
1051             while (pos < fieldEndPos) {
1052               target.add(readVarint32());
1053             }
1054             break;
1055           case WIRETYPE_VARINT:
1056             while (true) {
1057               target.add(readUInt32());
1058 
1059               if (isAtEnd()) {
1060                 return;
1061               }
1062               int prevPos = pos;
1063               int nextTag = readVarint32();
1064               if (nextTag != tag) {
1065                 // We've reached the end of the repeated field. Rewind the buffer position to before
1066                 // the new tag.
1067                 pos = prevPos;
1068                 return;
1069               }
1070             }
1071           default:
1072             throw InvalidProtocolBufferException.invalidWireType();
1073         }
1074       }
1075     }
1076 
1077     @Override
readEnumList(List<Integer> target)1078     public void readEnumList(List<Integer> target) throws IOException {
1079       if (target instanceof IntArrayList) {
1080         IntArrayList plist = (IntArrayList) target;
1081         switch (WireFormat.getTagWireType(tag)) {
1082           case WIRETYPE_LENGTH_DELIMITED:
1083             final int bytes = readVarint32();
1084             final int fieldEndPos = pos + bytes;
1085             while (pos < fieldEndPos) {
1086               plist.addInt(readVarint32());
1087             }
1088             break;
1089           case WIRETYPE_VARINT:
1090             while (true) {
1091               plist.addInt(readEnum());
1092 
1093               if (isAtEnd()) {
1094                 return;
1095               }
1096               int prevPos = pos;
1097               int nextTag = readVarint32();
1098               if (nextTag != tag) {
1099                 // We've reached the end of the repeated field. Rewind the buffer position to before
1100                 // the new tag.
1101                 pos = prevPos;
1102                 return;
1103               }
1104             }
1105           default:
1106             throw InvalidProtocolBufferException.invalidWireType();
1107         }
1108       } else {
1109         switch (WireFormat.getTagWireType(tag)) {
1110           case WIRETYPE_LENGTH_DELIMITED:
1111             final int bytes = readVarint32();
1112             final int fieldEndPos = pos + bytes;
1113             while (pos < fieldEndPos) {
1114               target.add(readVarint32());
1115             }
1116             break;
1117           case WIRETYPE_VARINT:
1118             while (true) {
1119               target.add(readEnum());
1120 
1121               if (isAtEnd()) {
1122                 return;
1123               }
1124               int prevPos = pos;
1125               int nextTag = readVarint32();
1126               if (nextTag != tag) {
1127                 // We've reached the end of the repeated field. Rewind the buffer position to before
1128                 // the new tag.
1129                 pos = prevPos;
1130                 return;
1131               }
1132             }
1133           default:
1134             throw InvalidProtocolBufferException.invalidWireType();
1135         }
1136       }
1137     }
1138 
1139     @Override
readSFixed32List(List<Integer> target)1140     public void readSFixed32List(List<Integer> target) throws IOException {
1141       if (target instanceof IntArrayList) {
1142         IntArrayList plist = (IntArrayList) target;
1143         switch (WireFormat.getTagWireType(tag)) {
1144           case WIRETYPE_LENGTH_DELIMITED:
1145             final int bytes = readVarint32();
1146             verifyPackedFixed32Length(bytes);
1147             final int fieldEndPos = pos + bytes;
1148             while (pos < fieldEndPos) {
1149               plist.addInt(readLittleEndian32_NoCheck());
1150             }
1151             break;
1152           case WIRETYPE_FIXED32:
1153             while (true) {
1154               plist.addInt(readSFixed32());
1155 
1156               if (isAtEnd()) {
1157                 return;
1158               }
1159               int prevPos = pos;
1160               int nextTag = readVarint32();
1161               if (nextTag != tag) {
1162                 // We've reached the end of the repeated field. Rewind the buffer position to before
1163                 // the new tag.
1164                 pos = prevPos;
1165                 return;
1166               }
1167             }
1168           default:
1169             throw InvalidProtocolBufferException.invalidWireType();
1170         }
1171       } else {
1172         switch (WireFormat.getTagWireType(tag)) {
1173           case WIRETYPE_LENGTH_DELIMITED:
1174             final int bytes = readVarint32();
1175             verifyPackedFixed32Length(bytes);
1176             final int fieldEndPos = pos + bytes;
1177             while (pos < fieldEndPos) {
1178               target.add(readLittleEndian32_NoCheck());
1179             }
1180             break;
1181           case WIRETYPE_FIXED32:
1182             while (true) {
1183               target.add(readSFixed32());
1184 
1185               if (isAtEnd()) {
1186                 return;
1187               }
1188               int prevPos = pos;
1189               int nextTag = readVarint32();
1190               if (nextTag != tag) {
1191                 // We've reached the end of the repeated field. Rewind the buffer position to before
1192                 // the new tag.
1193                 pos = prevPos;
1194                 return;
1195               }
1196             }
1197           default:
1198             throw InvalidProtocolBufferException.invalidWireType();
1199         }
1200       }
1201     }
1202 
1203     @Override
readSFixed64List(List<Long> target)1204     public void readSFixed64List(List<Long> target) throws IOException {
1205       if (target instanceof LongArrayList) {
1206         LongArrayList plist = (LongArrayList) target;
1207         switch (WireFormat.getTagWireType(tag)) {
1208           case WIRETYPE_LENGTH_DELIMITED:
1209             final int bytes = readVarint32();
1210             verifyPackedFixed64Length(bytes);
1211             final int fieldEndPos = pos + bytes;
1212             while (pos < fieldEndPos) {
1213               plist.addLong(readLittleEndian64_NoCheck());
1214             }
1215             break;
1216           case WIRETYPE_FIXED64:
1217             while (true) {
1218               plist.addLong(readSFixed64());
1219 
1220               if (isAtEnd()) {
1221                 return;
1222               }
1223               int prevPos = pos;
1224               int nextTag = readVarint32();
1225               if (nextTag != tag) {
1226                 // We've reached the end of the repeated field. Rewind the buffer position to before
1227                 // the new tag.
1228                 pos = prevPos;
1229                 return;
1230               }
1231             }
1232           default:
1233             throw InvalidProtocolBufferException.invalidWireType();
1234         }
1235       } else {
1236         switch (WireFormat.getTagWireType(tag)) {
1237           case WIRETYPE_LENGTH_DELIMITED:
1238             final int bytes = readVarint32();
1239             verifyPackedFixed64Length(bytes);
1240             final int fieldEndPos = pos + bytes;
1241             while (pos < fieldEndPos) {
1242               target.add(readLittleEndian64_NoCheck());
1243             }
1244             break;
1245           case WIRETYPE_FIXED64:
1246             while (true) {
1247               target.add(readSFixed64());
1248 
1249               if (isAtEnd()) {
1250                 return;
1251               }
1252               int prevPos = pos;
1253               int nextTag = readVarint32();
1254               if (nextTag != tag) {
1255                 // We've reached the end of the repeated field. Rewind the buffer position to before
1256                 // the new tag.
1257                 pos = prevPos;
1258                 return;
1259               }
1260             }
1261           default:
1262             throw InvalidProtocolBufferException.invalidWireType();
1263         }
1264       }
1265     }
1266 
1267     @Override
readSInt32List(List<Integer> target)1268     public void readSInt32List(List<Integer> target) throws IOException {
1269       if (target instanceof IntArrayList) {
1270         IntArrayList plist = (IntArrayList) target;
1271         switch (WireFormat.getTagWireType(tag)) {
1272           case WIRETYPE_LENGTH_DELIMITED:
1273             final int bytes = readVarint32();
1274             final int fieldEndPos = pos + bytes;
1275             while (pos < fieldEndPos) {
1276               plist.addInt(CodedInputStream.decodeZigZag32(readVarint32()));
1277             }
1278             break;
1279           case WIRETYPE_VARINT:
1280             while (true) {
1281               plist.addInt(readSInt32());
1282 
1283               if (isAtEnd()) {
1284                 return;
1285               }
1286               int prevPos = pos;
1287               int nextTag = readVarint32();
1288               if (nextTag != tag) {
1289                 // We've reached the end of the repeated field. Rewind the buffer position to before
1290                 // the new tag.
1291                 pos = prevPos;
1292                 return;
1293               }
1294             }
1295           default:
1296             throw InvalidProtocolBufferException.invalidWireType();
1297         }
1298       } else {
1299         switch (WireFormat.getTagWireType(tag)) {
1300           case WIRETYPE_LENGTH_DELIMITED:
1301             final int bytes = readVarint32();
1302             final int fieldEndPos = pos + bytes;
1303             while (pos < fieldEndPos) {
1304               target.add(CodedInputStream.decodeZigZag32(readVarint32()));
1305             }
1306             break;
1307           case WIRETYPE_VARINT:
1308             while (true) {
1309               target.add(readSInt32());
1310 
1311               if (isAtEnd()) {
1312                 return;
1313               }
1314               int prevPos = pos;
1315               int nextTag = readVarint32();
1316               if (nextTag != tag) {
1317                 // We've reached the end of the repeated field. Rewind the buffer position to before
1318                 // the new tag.
1319                 pos = prevPos;
1320                 return;
1321               }
1322             }
1323           default:
1324             throw InvalidProtocolBufferException.invalidWireType();
1325         }
1326       }
1327     }
1328 
1329     @Override
readSInt64List(List<Long> target)1330     public void readSInt64List(List<Long> target) throws IOException {
1331       if (target instanceof LongArrayList) {
1332         LongArrayList plist = (LongArrayList) target;
1333         switch (WireFormat.getTagWireType(tag)) {
1334           case WIRETYPE_LENGTH_DELIMITED:
1335             final int bytes = readVarint32();
1336             final int fieldEndPos = pos + bytes;
1337             while (pos < fieldEndPos) {
1338               plist.addLong(CodedInputStream.decodeZigZag64(readVarint64()));
1339             }
1340             break;
1341           case WIRETYPE_VARINT:
1342             while (true) {
1343               plist.addLong(readSInt64());
1344 
1345               if (isAtEnd()) {
1346                 return;
1347               }
1348               int prevPos = pos;
1349               int nextTag = readVarint32();
1350               if (nextTag != tag) {
1351                 // We've reached the end of the repeated field. Rewind the buffer position to before
1352                 // the new tag.
1353                 pos = prevPos;
1354                 return;
1355               }
1356             }
1357           default:
1358             throw InvalidProtocolBufferException.invalidWireType();
1359         }
1360       } else {
1361         switch (WireFormat.getTagWireType(tag)) {
1362           case WIRETYPE_LENGTH_DELIMITED:
1363             final int bytes = readVarint32();
1364             final int fieldEndPos = pos + bytes;
1365             while (pos < fieldEndPos) {
1366               target.add(CodedInputStream.decodeZigZag64(readVarint64()));
1367             }
1368             break;
1369           case WIRETYPE_VARINT:
1370             while (true) {
1371               target.add(readSInt64());
1372 
1373               if (isAtEnd()) {
1374                 return;
1375               }
1376               int prevPos = pos;
1377               int nextTag = readVarint32();
1378               if (nextTag != tag) {
1379                 // We've reached the end of the repeated field. Rewind the buffer position to before
1380                 // the new tag.
1381                 pos = prevPos;
1382                 return;
1383               }
1384             }
1385           default:
1386             throw InvalidProtocolBufferException.invalidWireType();
1387         }
1388       }
1389     }
1390 
1391     @SuppressWarnings("unchecked")
1392     @Override
readMap( Map<K, V> target, MapEntryLite.Metadata<K, V> metadata, ExtensionRegistryLite extensionRegistry)1393     public <K, V> void readMap(
1394         Map<K, V> target,
1395         MapEntryLite.Metadata<K, V> metadata,
1396         ExtensionRegistryLite extensionRegistry)
1397         throws IOException {
1398       requireWireType(WIRETYPE_LENGTH_DELIMITED);
1399       int size = readVarint32();
1400       requireBytes(size);
1401 
1402       // Update the limit.
1403       int prevLimit = limit;
1404       int newLimit = pos + size;
1405       limit = newLimit;
1406 
1407       try {
1408         K key = metadata.defaultKey;
1409         V value = metadata.defaultValue;
1410         while (true) {
1411           int number = getFieldNumber();
1412           if (number == READ_DONE) {
1413             break;
1414           }
1415           try {
1416             switch (number) {
1417               case 1:
1418                 key = (K) readField(metadata.keyType, null, null);
1419                 break;
1420               case 2:
1421                 value =
1422                     (V)
1423                         readField(
1424                             metadata.valueType,
1425                             metadata.defaultValue.getClass(),
1426                             extensionRegistry);
1427                 break;
1428               default:
1429                 if (!skipField()) {
1430                   throw new InvalidProtocolBufferException("Unable to parse map entry.");
1431                 }
1432                 break;
1433             }
1434           } catch (InvalidProtocolBufferException.InvalidWireTypeException ignore) {
1435             // the type doesn't match, skip the field.
1436             if (!skipField()) {
1437               throw new InvalidProtocolBufferException("Unable to parse map entry.");
1438             }
1439           }
1440         }
1441         target.put(key, value);
1442       } finally {
1443         // Restore the limit.
1444         limit = prevLimit;
1445       }
1446     }
1447 
readField( WireFormat.FieldType fieldType, Class<?> messageType, ExtensionRegistryLite extensionRegistry)1448     private Object readField(
1449         WireFormat.FieldType fieldType,
1450         Class<?> messageType,
1451         ExtensionRegistryLite extensionRegistry)
1452         throws IOException {
1453       switch (fieldType) {
1454         case BOOL:
1455           return readBool();
1456         case BYTES:
1457           return readBytes();
1458         case DOUBLE:
1459           return readDouble();
1460         case ENUM:
1461           return readEnum();
1462         case FIXED32:
1463           return readFixed32();
1464         case FIXED64:
1465           return readFixed64();
1466         case FLOAT:
1467           return readFloat();
1468         case INT32:
1469           return readInt32();
1470         case INT64:
1471           return readInt64();
1472         case MESSAGE:
1473           return readMessage(messageType, extensionRegistry);
1474         case SFIXED32:
1475           return readSFixed32();
1476         case SFIXED64:
1477           return readSFixed64();
1478         case SINT32:
1479           return readSInt32();
1480         case SINT64:
1481           return readSInt64();
1482         case STRING:
1483           return readStringRequireUtf8();
1484         case UINT32:
1485           return readUInt32();
1486         case UINT64:
1487           return readUInt64();
1488         default:
1489           throw new RuntimeException("unsupported field type.");
1490       }
1491     }
1492 
1493     /** Read a raw Varint from the stream. If larger than 32 bits, discard the upper bits. */
readVarint32()1494     private int readVarint32() throws IOException {
1495       // See implementation notes for readRawVarint64
1496       int i = pos;
1497 
1498       if (limit == pos) {
1499         throw InvalidProtocolBufferException.truncatedMessage();
1500       }
1501 
1502       int x;
1503       if ((x = buffer[i++]) >= 0) {
1504         pos = i;
1505         return x;
1506       } else if (limit - i < 9) {
1507         return (int) readVarint64SlowPath();
1508       } else if ((x ^= (buffer[i++] << 7)) < 0) {
1509         x ^= (~0 << 7);
1510       } else if ((x ^= (buffer[i++] << 14)) >= 0) {
1511         x ^= (~0 << 7) ^ (~0 << 14);
1512       } else if ((x ^= (buffer[i++] << 21)) < 0) {
1513         x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21);
1514       } else {
1515         int y = buffer[i++];
1516         x ^= y << 28;
1517         x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28);
1518         if (y < 0
1519             && buffer[i++] < 0
1520             && buffer[i++] < 0
1521             && buffer[i++] < 0
1522             && buffer[i++] < 0
1523             && buffer[i++] < 0) {
1524           throw InvalidProtocolBufferException.malformedVarint();
1525         }
1526       }
1527       pos = i;
1528       return x;
1529     }
1530 
readVarint64()1531     public long readVarint64() throws IOException {
1532       // Implementation notes:
1533       //
1534       // Optimized for one-byte values, expected to be common.
1535       // The particular code below was selected from various candidates
1536       // empirically, by winning VarintBenchmark.
1537       //
1538       // Sign extension of (signed) Java bytes is usually a nuisance, but
1539       // we exploit it here to more easily obtain the sign of bytes read.
1540       // Instead of cleaning up the sign extension bits by masking eagerly,
1541       // we delay until we find the final (positive) byte, when we clear all
1542       // accumulated bits with one xor.  We depend on javac to constant fold.
1543       int i = pos;
1544 
1545       if (limit == i) {
1546         throw InvalidProtocolBufferException.truncatedMessage();
1547       }
1548 
1549       final byte[] buffer = this.buffer;
1550       long x;
1551       int y;
1552       if ((y = buffer[i++]) >= 0) {
1553         pos = i;
1554         return y;
1555       } else if (limit - i < 9) {
1556         return readVarint64SlowPath();
1557       } else if ((y ^= (buffer[i++] << 7)) < 0) {
1558         x = y ^ (~0 << 7);
1559       } else if ((y ^= (buffer[i++] << 14)) >= 0) {
1560         x = y ^ ((~0 << 7) ^ (~0 << 14));
1561       } else if ((y ^= (buffer[i++] << 21)) < 0) {
1562         x = y ^ ((~0 << 7) ^ (~0 << 14) ^ (~0 << 21));
1563       } else if ((x = y ^ ((long) buffer[i++] << 28)) >= 0L) {
1564         x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
1565       } else if ((x ^= ((long) buffer[i++] << 35)) < 0L) {
1566         x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
1567       } else if ((x ^= ((long) buffer[i++] << 42)) >= 0L) {
1568         x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
1569       } else if ((x ^= ((long) buffer[i++] << 49)) < 0L) {
1570         x ^=
1571             (~0L << 7)
1572                 ^ (~0L << 14)
1573                 ^ (~0L << 21)
1574                 ^ (~0L << 28)
1575                 ^ (~0L << 35)
1576                 ^ (~0L << 42)
1577                 ^ (~0L << 49);
1578       } else {
1579         x ^= ((long) buffer[i++] << 56);
1580         x ^=
1581             (~0L << 7)
1582                 ^ (~0L << 14)
1583                 ^ (~0L << 21)
1584                 ^ (~0L << 28)
1585                 ^ (~0L << 35)
1586                 ^ (~0L << 42)
1587                 ^ (~0L << 49)
1588                 ^ (~0L << 56);
1589         if (x < 0L) {
1590           if (buffer[i++] < 0L) {
1591             throw InvalidProtocolBufferException.malformedVarint();
1592           }
1593         }
1594       }
1595       pos = i;
1596       return x;
1597     }
1598 
readVarint64SlowPath()1599     private long readVarint64SlowPath() throws IOException {
1600       long result = 0;
1601       for (int shift = 0; shift < 64; shift += 7) {
1602         final byte b = readByte();
1603         result |= (long) (b & 0x7F) << shift;
1604         if ((b & 0x80) == 0) {
1605           return result;
1606         }
1607       }
1608       throw InvalidProtocolBufferException.malformedVarint();
1609     }
1610 
readByte()1611     private byte readByte() throws IOException {
1612       if (pos == limit) {
1613         throw InvalidProtocolBufferException.truncatedMessage();
1614       }
1615       return buffer[pos++];
1616     }
1617 
readLittleEndian32()1618     private int readLittleEndian32() throws IOException {
1619       requireBytes(FIXED32_SIZE);
1620       return readLittleEndian32_NoCheck();
1621     }
1622 
readLittleEndian64()1623     private long readLittleEndian64() throws IOException {
1624       requireBytes(FIXED64_SIZE);
1625       return readLittleEndian64_NoCheck();
1626     }
1627 
readLittleEndian32_NoCheck()1628     private int readLittleEndian32_NoCheck() {
1629       int p = pos;
1630       final byte[] buffer = this.buffer;
1631       pos = p + FIXED32_SIZE;
1632       return (((buffer[p] & 0xff))
1633           | ((buffer[p + 1] & 0xff) << 8)
1634           | ((buffer[p + 2] & 0xff) << 16)
1635           | ((buffer[p + 3] & 0xff) << 24));
1636     }
1637 
readLittleEndian64_NoCheck()1638     private long readLittleEndian64_NoCheck() {
1639       int p = pos;
1640       final byte[] buffer = this.buffer;
1641       pos = p + FIXED64_SIZE;
1642       return (((buffer[p] & 0xffL))
1643           | ((buffer[p + 1] & 0xffL) << 8)
1644           | ((buffer[p + 2] & 0xffL) << 16)
1645           | ((buffer[p + 3] & 0xffL) << 24)
1646           | ((buffer[p + 4] & 0xffL) << 32)
1647           | ((buffer[p + 5] & 0xffL) << 40)
1648           | ((buffer[p + 6] & 0xffL) << 48)
1649           | ((buffer[p + 7] & 0xffL) << 56));
1650     }
1651 
skipVarint()1652     private void skipVarint() throws IOException {
1653       if (limit - pos >= 10) {
1654         final byte[] buffer = this.buffer;
1655         int p = pos;
1656         for (int i = 0; i < 10; i++) {
1657           if (buffer[p++] >= 0) {
1658             pos = p;
1659             return;
1660           }
1661         }
1662       }
1663       skipVarintSlowPath();
1664     }
1665 
skipVarintSlowPath()1666     private void skipVarintSlowPath() throws IOException {
1667       for (int i = 0; i < 10; i++) {
1668         if (readByte() >= 0) {
1669           return;
1670         }
1671       }
1672       throw InvalidProtocolBufferException.malformedVarint();
1673     }
1674 
skipBytes(final int size)1675     private void skipBytes(final int size) throws IOException {
1676       requireBytes(size);
1677 
1678       pos += size;
1679     }
1680 
skipGroup()1681     private void skipGroup() throws IOException {
1682       int prevEndGroupTag = endGroupTag;
1683       endGroupTag = WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WIRETYPE_END_GROUP);
1684       while (true) {
1685         if (getFieldNumber() == READ_DONE || !skipField()) {
1686           break;
1687         }
1688       }
1689       if (tag != endGroupTag) {
1690         throw InvalidProtocolBufferException.parseFailure();
1691       }
1692       endGroupTag = prevEndGroupTag;
1693     }
1694 
requireBytes(int size)1695     private void requireBytes(int size) throws IOException {
1696       if (size < 0 || size > (limit - pos)) {
1697         throw InvalidProtocolBufferException.truncatedMessage();
1698       }
1699     }
1700 
requireWireType(int requiredWireType)1701     private void requireWireType(int requiredWireType) throws IOException {
1702       if (WireFormat.getTagWireType(tag) != requiredWireType) {
1703         throw InvalidProtocolBufferException.invalidWireType();
1704       }
1705     }
1706 
verifyPackedFixed64Length(int bytes)1707     private void verifyPackedFixed64Length(int bytes) throws IOException {
1708       requireBytes(bytes);
1709       if ((bytes & FIXED64_MULTIPLE_MASK) != 0) {
1710         // Require that the number of bytes be a multiple of 8.
1711         throw InvalidProtocolBufferException.parseFailure();
1712       }
1713     }
1714 
verifyPackedFixed32Length(int bytes)1715     private void verifyPackedFixed32Length(int bytes) throws IOException {
1716       requireBytes(bytes);
1717       if ((bytes & FIXED32_MULTIPLE_MASK) != 0) {
1718         // Require that the number of bytes be a multiple of 4.
1719         throw InvalidProtocolBufferException.parseFailure();
1720       }
1721     }
1722 
requirePosition(int expectedPosition)1723     private void requirePosition(int expectedPosition) throws IOException {
1724       if (pos != expectedPosition) {
1725         throw InvalidProtocolBufferException.truncatedMessage();
1726       }
1727     }
1728   }
1729 }
1730