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.util.List; 44 import java.util.Map; 45 46 /** An adapter between the {@link Reader} interface and {@link CodedInputStream}. */ 47 @ExperimentalApi 48 final class CodedInputStreamReader implements Reader { 49 private static final int FIXED32_MULTIPLE_MASK = FIXED32_SIZE - 1; 50 private static final int FIXED64_MULTIPLE_MASK = FIXED64_SIZE - 1; 51 private static final int NEXT_TAG_UNSET = 0; 52 53 private final CodedInputStream input; 54 private int tag; 55 private int endGroupTag; 56 private int nextTag = NEXT_TAG_UNSET; 57 forCodedInput(CodedInputStream input)58 public static CodedInputStreamReader forCodedInput(CodedInputStream input) { 59 if (input.wrapper != null) { 60 return input.wrapper; 61 } 62 return new CodedInputStreamReader(input); 63 } 64 CodedInputStreamReader(CodedInputStream input)65 private CodedInputStreamReader(CodedInputStream input) { 66 this.input = Internal.checkNotNull(input, "input"); 67 this.input.wrapper = this; 68 } 69 70 @Override shouldDiscardUnknownFields()71 public boolean shouldDiscardUnknownFields() { 72 return input.shouldDiscardUnknownFields(); 73 } 74 75 @Override getFieldNumber()76 public int getFieldNumber() throws IOException { 77 if (nextTag != NEXT_TAG_UNSET) { 78 tag = nextTag; 79 nextTag = NEXT_TAG_UNSET; 80 } else { 81 tag = input.readTag(); 82 } 83 if (tag == 0 || tag == endGroupTag) { 84 return Reader.READ_DONE; 85 } 86 return WireFormat.getTagFieldNumber(tag); 87 } 88 89 @Override getTag()90 public int getTag() { 91 return tag; 92 } 93 94 @Override skipField()95 public boolean skipField() throws IOException { 96 if (input.isAtEnd() || tag == endGroupTag) { 97 return false; 98 } 99 return input.skipField(tag); 100 } 101 requireWireType(int requiredWireType)102 private void requireWireType(int requiredWireType) throws IOException { 103 if (WireFormat.getTagWireType(tag) != requiredWireType) { 104 throw InvalidProtocolBufferException.invalidWireType(); 105 } 106 } 107 108 @Override readDouble()109 public double readDouble() throws IOException { 110 requireWireType(WIRETYPE_FIXED64); 111 return input.readDouble(); 112 } 113 114 @Override readFloat()115 public float readFloat() throws IOException { 116 requireWireType(WIRETYPE_FIXED32); 117 return input.readFloat(); 118 } 119 120 @Override readUInt64()121 public long readUInt64() throws IOException { 122 requireWireType(WIRETYPE_VARINT); 123 return input.readUInt64(); 124 } 125 126 @Override readInt64()127 public long readInt64() throws IOException { 128 requireWireType(WIRETYPE_VARINT); 129 return input.readInt64(); 130 } 131 132 @Override readInt32()133 public int readInt32() throws IOException { 134 requireWireType(WIRETYPE_VARINT); 135 return input.readInt32(); 136 } 137 138 @Override readFixed64()139 public long readFixed64() throws IOException { 140 requireWireType(WIRETYPE_FIXED64); 141 return input.readFixed64(); 142 } 143 144 @Override readFixed32()145 public int readFixed32() throws IOException { 146 requireWireType(WIRETYPE_FIXED32); 147 return input.readFixed32(); 148 } 149 150 @Override readBool()151 public boolean readBool() throws IOException { 152 requireWireType(WIRETYPE_VARINT); 153 return input.readBool(); 154 } 155 156 @Override readString()157 public String readString() throws IOException { 158 requireWireType(WIRETYPE_LENGTH_DELIMITED); 159 return input.readString(); 160 } 161 162 @Override readStringRequireUtf8()163 public String readStringRequireUtf8() throws IOException { 164 requireWireType(WIRETYPE_LENGTH_DELIMITED); 165 return input.readStringRequireUtf8(); 166 } 167 168 @SuppressWarnings("unchecked") 169 @Override readMessage(Class<T> clazz, ExtensionRegistryLite extensionRegistry)170 public <T> T readMessage(Class<T> clazz, ExtensionRegistryLite extensionRegistry) 171 throws IOException { 172 requireWireType(WIRETYPE_LENGTH_DELIMITED); 173 return readMessage(Protobuf.getInstance().schemaFor(clazz), extensionRegistry); 174 } 175 176 @SuppressWarnings("unchecked") 177 @Override readMessageBySchemaWithCheck( Schema<T> schema, ExtensionRegistryLite extensionRegistry)178 public <T> T readMessageBySchemaWithCheck( 179 Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException { 180 requireWireType(WIRETYPE_LENGTH_DELIMITED); 181 return readMessage(schema, extensionRegistry); 182 } 183 184 @SuppressWarnings("unchecked") 185 @Override readGroup(Class<T> clazz, ExtensionRegistryLite extensionRegistry)186 public <T> T readGroup(Class<T> clazz, ExtensionRegistryLite extensionRegistry) 187 throws IOException { 188 requireWireType(WIRETYPE_START_GROUP); 189 return readGroup(Protobuf.getInstance().schemaFor(clazz), extensionRegistry); 190 } 191 192 @SuppressWarnings("unchecked") 193 @Override readGroupBySchemaWithCheck(Schema<T> schema, ExtensionRegistryLite extensionRegistry)194 public <T> T readGroupBySchemaWithCheck(Schema<T> schema, ExtensionRegistryLite extensionRegistry) 195 throws IOException { 196 requireWireType(WIRETYPE_START_GROUP); 197 return readGroup(schema, extensionRegistry); 198 } 199 200 @Override mergeMessageField( T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)201 public <T> void mergeMessageField( 202 T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException { 203 requireWireType(WIRETYPE_LENGTH_DELIMITED); 204 mergeMessageFieldInternal(target, schema, extensionRegistry); 205 } 206 mergeMessageFieldInternal( T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)207 private <T> void mergeMessageFieldInternal( 208 T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException { 209 int size = input.readUInt32(); 210 if (input.recursionDepth >= input.recursionLimit) { 211 throw InvalidProtocolBufferException.recursionLimitExceeded(); 212 } 213 214 // Push the new limit. 215 final int prevLimit = input.pushLimit(size); 216 ++input.recursionDepth; 217 schema.mergeFrom(target, this, extensionRegistry); 218 input.checkLastTagWas(0); 219 --input.recursionDepth; 220 // Restore the previous limit. 221 input.popLimit(prevLimit); 222 } 223 224 // Should have the same semantics of CodedInputStream#readMessage() readMessage(Schema<T> schema, ExtensionRegistryLite extensionRegistry)225 private <T> T readMessage(Schema<T> schema, ExtensionRegistryLite extensionRegistry) 226 throws IOException { 227 T newInstance = schema.newInstance(); 228 mergeMessageFieldInternal(newInstance, schema, extensionRegistry); 229 schema.makeImmutable(newInstance); 230 return newInstance; 231 } 232 233 @Override mergeGroupField( T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)234 public <T> void mergeGroupField( 235 T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException { 236 requireWireType(WIRETYPE_START_GROUP); 237 mergeGroupFieldInternal(target, schema, extensionRegistry); 238 } 239 mergeGroupFieldInternal( T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)240 private <T> void mergeGroupFieldInternal( 241 T target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException { 242 int prevEndGroupTag = endGroupTag; 243 endGroupTag = WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WIRETYPE_END_GROUP); 244 245 try { 246 schema.mergeFrom(target, this, extensionRegistry); 247 if (tag != endGroupTag) { 248 throw InvalidProtocolBufferException.parseFailure(); 249 } 250 } finally { 251 // Restore the old end group tag. 252 endGroupTag = prevEndGroupTag; 253 } 254 } 255 readGroup(Schema<T> schema, ExtensionRegistryLite extensionRegistry)256 private <T> T readGroup(Schema<T> schema, ExtensionRegistryLite extensionRegistry) 257 throws IOException { 258 T newInstance = schema.newInstance(); 259 mergeGroupFieldInternal(newInstance, schema, extensionRegistry); 260 schema.makeImmutable(newInstance); 261 return newInstance; 262 } 263 264 @Override readBytes()265 public ByteString readBytes() throws IOException { 266 requireWireType(WIRETYPE_LENGTH_DELIMITED); 267 return input.readBytes(); 268 } 269 270 @Override readUInt32()271 public int readUInt32() throws IOException { 272 requireWireType(WIRETYPE_VARINT); 273 return input.readUInt32(); 274 } 275 276 @Override readEnum()277 public int readEnum() throws IOException { 278 requireWireType(WIRETYPE_VARINT); 279 return input.readEnum(); 280 } 281 282 @Override readSFixed32()283 public int readSFixed32() throws IOException { 284 requireWireType(WIRETYPE_FIXED32); 285 return input.readSFixed32(); 286 } 287 288 @Override readSFixed64()289 public long readSFixed64() throws IOException { 290 requireWireType(WIRETYPE_FIXED64); 291 return input.readSFixed64(); 292 } 293 294 @Override readSInt32()295 public int readSInt32() throws IOException { 296 requireWireType(WIRETYPE_VARINT); 297 return input.readSInt32(); 298 } 299 300 @Override readSInt64()301 public long readSInt64() throws IOException { 302 requireWireType(WIRETYPE_VARINT); 303 return input.readSInt64(); 304 } 305 306 @Override readDoubleList(List<Double> target)307 public void readDoubleList(List<Double> target) throws IOException { 308 if (target instanceof DoubleArrayList) { 309 DoubleArrayList plist = (DoubleArrayList) target; 310 switch (WireFormat.getTagWireType(tag)) { 311 case WIRETYPE_LENGTH_DELIMITED: 312 final int bytes = input.readUInt32(); 313 verifyPackedFixed64Length(bytes); 314 int endPos = input.getTotalBytesRead() + bytes; 315 do { 316 plist.addDouble(input.readDouble()); 317 } while (input.getTotalBytesRead() < endPos); 318 break; 319 case WIRETYPE_FIXED64: 320 while (true) { 321 plist.addDouble(input.readDouble()); 322 if (input.isAtEnd()) { 323 return; 324 } 325 int nextTag = input.readTag(); 326 if (nextTag != tag) { 327 // We've reached the end of the repeated field. Save the next tag value. 328 this.nextTag = nextTag; 329 return; 330 } 331 } 332 default: 333 throw InvalidProtocolBufferException.invalidWireType(); 334 } 335 } else { 336 switch (WireFormat.getTagWireType(tag)) { 337 case WIRETYPE_LENGTH_DELIMITED: 338 final int bytes = input.readUInt32(); 339 verifyPackedFixed64Length(bytes); 340 int endPos = input.getTotalBytesRead() + bytes; 341 do { 342 target.add(input.readDouble()); 343 } while (input.getTotalBytesRead() < endPos); 344 break; 345 case WIRETYPE_FIXED64: 346 while (true) { 347 target.add(input.readDouble()); 348 if (input.isAtEnd()) { 349 return; 350 } 351 int nextTag = input.readTag(); 352 if (nextTag != tag) { 353 // We've reached the end of the repeated field. Save the next tag value. 354 this.nextTag = nextTag; 355 return; 356 } 357 } 358 default: 359 throw InvalidProtocolBufferException.invalidWireType(); 360 } 361 } 362 } 363 364 @Override readFloatList(List<Float> target)365 public void readFloatList(List<Float> target) throws IOException { 366 if (target instanceof FloatArrayList) { 367 FloatArrayList plist = (FloatArrayList) target; 368 switch (WireFormat.getTagWireType(tag)) { 369 case WIRETYPE_LENGTH_DELIMITED: 370 final int bytes = input.readUInt32(); 371 verifyPackedFixed32Length(bytes); 372 int endPos = input.getTotalBytesRead() + bytes; 373 do { 374 plist.addFloat(input.readFloat()); 375 } while (input.getTotalBytesRead() < endPos); 376 break; 377 case WIRETYPE_FIXED32: 378 while (true) { 379 plist.addFloat(input.readFloat()); 380 if (input.isAtEnd()) { 381 return; 382 } 383 int nextTag = input.readTag(); 384 if (nextTag != tag) { 385 // We've reached the end of the repeated field. Save the next tag value. 386 this.nextTag = nextTag; 387 return; 388 } 389 } 390 default: 391 throw InvalidProtocolBufferException.invalidWireType(); 392 } 393 } else { 394 switch (WireFormat.getTagWireType(tag)) { 395 case WIRETYPE_LENGTH_DELIMITED: 396 final int bytes = input.readUInt32(); 397 verifyPackedFixed32Length(bytes); 398 int endPos = input.getTotalBytesRead() + bytes; 399 do { 400 target.add(input.readFloat()); 401 } while (input.getTotalBytesRead() < endPos); 402 break; 403 case WIRETYPE_FIXED32: 404 while (true) { 405 target.add(input.readFloat()); 406 if (input.isAtEnd()) { 407 return; 408 } 409 int nextTag = input.readTag(); 410 if (nextTag != tag) { 411 // We've reached the end of the repeated field. Save the next tag value. 412 this.nextTag = nextTag; 413 return; 414 } 415 } 416 default: 417 throw InvalidProtocolBufferException.invalidWireType(); 418 } 419 } 420 } 421 422 @Override readUInt64List(List<Long> target)423 public void readUInt64List(List<Long> target) throws IOException { 424 if (target instanceof LongArrayList) { 425 LongArrayList plist = (LongArrayList) target; 426 switch (WireFormat.getTagWireType(tag)) { 427 case WIRETYPE_LENGTH_DELIMITED: 428 final int bytes = input.readUInt32(); 429 int endPos = input.getTotalBytesRead() + bytes; 430 do { 431 plist.addLong(input.readUInt64()); 432 } while (input.getTotalBytesRead() < endPos); 433 requirePosition(endPos); 434 break; 435 case WIRETYPE_VARINT: 436 while (true) { 437 plist.addLong(input.readUInt64()); 438 if (input.isAtEnd()) { 439 return; 440 } 441 int nextTag = input.readTag(); 442 if (nextTag != tag) { 443 // We've reached the end of the repeated field. Save the next tag value. 444 this.nextTag = nextTag; 445 return; 446 } 447 } 448 default: 449 throw InvalidProtocolBufferException.invalidWireType(); 450 } 451 } else { 452 switch (WireFormat.getTagWireType(tag)) { 453 case WIRETYPE_LENGTH_DELIMITED: 454 final int bytes = input.readUInt32(); 455 int endPos = input.getTotalBytesRead() + bytes; 456 do { 457 target.add(input.readUInt64()); 458 } while (input.getTotalBytesRead() < endPos); 459 requirePosition(endPos); 460 break; 461 case WIRETYPE_VARINT: 462 while (true) { 463 target.add(input.readUInt64()); 464 if (input.isAtEnd()) { 465 return; 466 } 467 int nextTag = input.readTag(); 468 if (nextTag != tag) { 469 // We've reached the end of the repeated field. Save the next tag value. 470 this.nextTag = nextTag; 471 return; 472 } 473 } 474 default: 475 throw InvalidProtocolBufferException.invalidWireType(); 476 } 477 } 478 } 479 480 @Override readInt64List(List<Long> target)481 public void readInt64List(List<Long> target) throws IOException { 482 if (target instanceof LongArrayList) { 483 LongArrayList plist = (LongArrayList) target; 484 switch (WireFormat.getTagWireType(tag)) { 485 case WIRETYPE_LENGTH_DELIMITED: 486 final int bytes = input.readUInt32(); 487 int endPos = input.getTotalBytesRead() + bytes; 488 do { 489 plist.addLong(input.readInt64()); 490 } while (input.getTotalBytesRead() < endPos); 491 requirePosition(endPos); 492 break; 493 case WIRETYPE_VARINT: 494 while (true) { 495 plist.addLong(input.readInt64()); 496 if (input.isAtEnd()) { 497 return; 498 } 499 int nextTag = input.readTag(); 500 if (nextTag != tag) { 501 // We've reached the end of the repeated field. Save the next tag value. 502 this.nextTag = nextTag; 503 return; 504 } 505 } 506 default: 507 throw InvalidProtocolBufferException.invalidWireType(); 508 } 509 } else { 510 switch (WireFormat.getTagWireType(tag)) { 511 case WIRETYPE_LENGTH_DELIMITED: 512 final int bytes = input.readUInt32(); 513 int endPos = input.getTotalBytesRead() + bytes; 514 do { 515 target.add(input.readInt64()); 516 } while (input.getTotalBytesRead() < endPos); 517 requirePosition(endPos); 518 break; 519 case WIRETYPE_VARINT: 520 while (true) { 521 target.add(input.readInt64()); 522 if (input.isAtEnd()) { 523 return; 524 } 525 int nextTag = input.readTag(); 526 if (nextTag != tag) { 527 // We've reached the end of the repeated field. Save the next tag value. 528 this.nextTag = nextTag; 529 return; 530 } 531 } 532 default: 533 throw InvalidProtocolBufferException.invalidWireType(); 534 } 535 } 536 } 537 538 @Override readInt32List(List<Integer> target)539 public void readInt32List(List<Integer> target) throws IOException { 540 if (target instanceof IntArrayList) { 541 IntArrayList plist = (IntArrayList) target; 542 switch (WireFormat.getTagWireType(tag)) { 543 case WIRETYPE_LENGTH_DELIMITED: 544 final int bytes = input.readUInt32(); 545 int endPos = input.getTotalBytesRead() + bytes; 546 do { 547 plist.addInt(input.readInt32()); 548 } while (input.getTotalBytesRead() < endPos); 549 requirePosition(endPos); 550 break; 551 case WIRETYPE_VARINT: 552 while (true) { 553 plist.addInt(input.readInt32()); 554 if (input.isAtEnd()) { 555 return; 556 } 557 int nextTag = input.readTag(); 558 if (nextTag != tag) { 559 // We've reached the end of the repeated field. Save the next tag value. 560 this.nextTag = nextTag; 561 return; 562 } 563 } 564 default: 565 throw InvalidProtocolBufferException.invalidWireType(); 566 } 567 } else { 568 switch (WireFormat.getTagWireType(tag)) { 569 case WIRETYPE_LENGTH_DELIMITED: 570 final int bytes = input.readUInt32(); 571 int endPos = input.getTotalBytesRead() + bytes; 572 do { 573 target.add(input.readInt32()); 574 } while (input.getTotalBytesRead() < endPos); 575 requirePosition(endPos); 576 break; 577 case WIRETYPE_VARINT: 578 while (true) { 579 target.add(input.readInt32()); 580 if (input.isAtEnd()) { 581 return; 582 } 583 int nextTag = input.readTag(); 584 if (nextTag != tag) { 585 // We've reached the end of the repeated field. Save the next tag value. 586 this.nextTag = nextTag; 587 return; 588 } 589 } 590 default: 591 throw InvalidProtocolBufferException.invalidWireType(); 592 } 593 } 594 } 595 596 @Override readFixed64List(List<Long> target)597 public void readFixed64List(List<Long> target) throws IOException { 598 if (target instanceof LongArrayList) { 599 LongArrayList plist = (LongArrayList) target; 600 switch (WireFormat.getTagWireType(tag)) { 601 case WIRETYPE_LENGTH_DELIMITED: 602 final int bytes = input.readUInt32(); 603 verifyPackedFixed64Length(bytes); 604 int endPos = input.getTotalBytesRead() + bytes; 605 do { 606 plist.addLong(input.readFixed64()); 607 } while (input.getTotalBytesRead() < endPos); 608 break; 609 case WIRETYPE_FIXED64: 610 while (true) { 611 plist.addLong(input.readFixed64()); 612 if (input.isAtEnd()) { 613 return; 614 } 615 int nextTag = input.readTag(); 616 if (nextTag != tag) { 617 // We've reached the end of the repeated field. Save the next tag value. 618 this.nextTag = nextTag; 619 return; 620 } 621 } 622 default: 623 throw InvalidProtocolBufferException.invalidWireType(); 624 } 625 } else { 626 switch (WireFormat.getTagWireType(tag)) { 627 case WIRETYPE_LENGTH_DELIMITED: 628 final int bytes = input.readUInt32(); 629 verifyPackedFixed64Length(bytes); 630 int endPos = input.getTotalBytesRead() + bytes; 631 do { 632 target.add(input.readFixed64()); 633 } while (input.getTotalBytesRead() < endPos); 634 break; 635 case WIRETYPE_FIXED64: 636 while (true) { 637 target.add(input.readFixed64()); 638 if (input.isAtEnd()) { 639 return; 640 } 641 int nextTag = input.readTag(); 642 if (nextTag != tag) { 643 // We've reached the end of the repeated field. Save the next tag value. 644 this.nextTag = nextTag; 645 return; 646 } 647 } 648 default: 649 throw InvalidProtocolBufferException.invalidWireType(); 650 } 651 } 652 } 653 654 @Override readFixed32List(List<Integer> target)655 public void readFixed32List(List<Integer> target) throws IOException { 656 if (target instanceof IntArrayList) { 657 IntArrayList plist = (IntArrayList) target; 658 switch (WireFormat.getTagWireType(tag)) { 659 case WIRETYPE_LENGTH_DELIMITED: 660 final int bytes = input.readUInt32(); 661 verifyPackedFixed32Length(bytes); 662 int endPos = input.getTotalBytesRead() + bytes; 663 do { 664 plist.addInt(input.readFixed32()); 665 } while (input.getTotalBytesRead() < endPos); 666 break; 667 case WIRETYPE_FIXED32: 668 while (true) { 669 plist.addInt(input.readFixed32()); 670 if (input.isAtEnd()) { 671 return; 672 } 673 int nextTag = input.readTag(); 674 if (nextTag != tag) { 675 // We've reached the end of the repeated field. Save the next tag value. 676 this.nextTag = nextTag; 677 return; 678 } 679 } 680 default: 681 throw InvalidProtocolBufferException.invalidWireType(); 682 } 683 } else { 684 switch (WireFormat.getTagWireType(tag)) { 685 case WIRETYPE_LENGTH_DELIMITED: 686 final int bytes = input.readUInt32(); 687 verifyPackedFixed32Length(bytes); 688 int endPos = input.getTotalBytesRead() + bytes; 689 do { 690 target.add(input.readFixed32()); 691 } while (input.getTotalBytesRead() < endPos); 692 break; 693 case WIRETYPE_FIXED32: 694 while (true) { 695 target.add(input.readFixed32()); 696 if (input.isAtEnd()) { 697 return; 698 } 699 int nextTag = input.readTag(); 700 if (nextTag != tag) { 701 // We've reached the end of the repeated field. Save the next tag value. 702 this.nextTag = nextTag; 703 return; 704 } 705 } 706 default: 707 throw InvalidProtocolBufferException.invalidWireType(); 708 } 709 } 710 } 711 712 @Override readBoolList(List<Boolean> target)713 public void readBoolList(List<Boolean> target) throws IOException { 714 if (target instanceof BooleanArrayList) { 715 BooleanArrayList plist = (BooleanArrayList) target; 716 switch (WireFormat.getTagWireType(tag)) { 717 case WIRETYPE_LENGTH_DELIMITED: 718 final int bytes = input.readUInt32(); 719 int endPos = input.getTotalBytesRead() + bytes; 720 do { 721 plist.addBoolean(input.readBool()); 722 } while (input.getTotalBytesRead() < endPos); 723 requirePosition(endPos); 724 break; 725 case WIRETYPE_VARINT: 726 while (true) { 727 plist.addBoolean(input.readBool()); 728 if (input.isAtEnd()) { 729 return; 730 } 731 int nextTag = input.readTag(); 732 if (nextTag != tag) { 733 // We've reached the end of the repeated field. Save the next tag value. 734 this.nextTag = nextTag; 735 return; 736 } 737 } 738 default: 739 throw InvalidProtocolBufferException.invalidWireType(); 740 } 741 } else { 742 switch (WireFormat.getTagWireType(tag)) { 743 case WIRETYPE_LENGTH_DELIMITED: 744 final int bytes = input.readUInt32(); 745 int endPos = input.getTotalBytesRead() + bytes; 746 do { 747 target.add(input.readBool()); 748 } while (input.getTotalBytesRead() < endPos); 749 requirePosition(endPos); 750 break; 751 case WIRETYPE_VARINT: 752 while (true) { 753 target.add(input.readBool()); 754 if (input.isAtEnd()) { 755 return; 756 } 757 int nextTag = input.readTag(); 758 if (nextTag != tag) { 759 // We've reached the end of the repeated field. Save the next tag value. 760 this.nextTag = nextTag; 761 return; 762 } 763 } 764 default: 765 throw InvalidProtocolBufferException.invalidWireType(); 766 } 767 } 768 } 769 770 @Override readStringList(List<String> target)771 public void readStringList(List<String> target) throws IOException { 772 readStringListInternal(target, false); 773 } 774 775 @Override readStringListRequireUtf8(List<String> target)776 public void readStringListRequireUtf8(List<String> target) throws IOException { 777 readStringListInternal(target, true); 778 } 779 readStringListInternal(List<String> target, boolean requireUtf8)780 public void readStringListInternal(List<String> target, boolean requireUtf8) throws IOException { 781 if (WireFormat.getTagWireType(tag) != WIRETYPE_LENGTH_DELIMITED) { 782 throw InvalidProtocolBufferException.invalidWireType(); 783 } 784 785 if (target instanceof LazyStringList && !requireUtf8) { 786 LazyStringList lazyList = (LazyStringList) target; 787 while (true) { 788 lazyList.add(readBytes()); 789 if (input.isAtEnd()) { 790 return; 791 } 792 int nextTag = input.readTag(); 793 if (nextTag != tag) { 794 // We've reached the end of the repeated field. Save the next tag value. 795 this.nextTag = nextTag; 796 return; 797 } 798 } 799 } else { 800 while (true) { 801 target.add(requireUtf8 ? readStringRequireUtf8() : readString()); 802 if (input.isAtEnd()) { 803 return; 804 } 805 int nextTag = input.readTag(); 806 if (nextTag != tag) { 807 // We've reached the end of the repeated field. Save the next tag value. 808 this.nextTag = nextTag; 809 return; 810 } 811 } 812 } 813 } 814 815 @Override readMessageList( List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry)816 public <T> void readMessageList( 817 List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry) 818 throws IOException { 819 final Schema<T> schema = Protobuf.getInstance().schemaFor(targetType); 820 readMessageList(target, schema, extensionRegistry); 821 } 822 823 @Override readMessageList( List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)824 public <T> void readMessageList( 825 List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) 826 throws IOException { 827 if (WireFormat.getTagWireType(tag) != WIRETYPE_LENGTH_DELIMITED) { 828 throw InvalidProtocolBufferException.invalidWireType(); 829 } 830 final int listTag = tag; 831 while (true) { 832 target.add(readMessage(schema, extensionRegistry)); 833 if (input.isAtEnd() || nextTag != NEXT_TAG_UNSET) { 834 return; 835 } 836 int nextTag = input.readTag(); 837 if (nextTag != listTag) { 838 // We've reached the end of the repeated field. Save the next tag value. 839 this.nextTag = nextTag; 840 return; 841 } 842 } 843 } 844 845 @Override readGroupList( List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry)846 public <T> void readGroupList( 847 List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry) 848 throws IOException { 849 final Schema<T> schema = Protobuf.getInstance().schemaFor(targetType); 850 readGroupList(target, schema, extensionRegistry); 851 } 852 853 @Override readGroupList( List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry)854 public <T> void readGroupList( 855 List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) 856 throws IOException { 857 if (WireFormat.getTagWireType(tag) != WIRETYPE_START_GROUP) { 858 throw InvalidProtocolBufferException.invalidWireType(); 859 } 860 final int listTag = tag; 861 while (true) { 862 target.add(readGroup(schema, extensionRegistry)); 863 if (input.isAtEnd() || nextTag != NEXT_TAG_UNSET) { 864 return; 865 } 866 int nextTag = input.readTag(); 867 if (nextTag != listTag) { 868 // We've reached the end of the repeated field. Save the next tag value. 869 this.nextTag = nextTag; 870 return; 871 } 872 } 873 } 874 875 @Override readBytesList(List<ByteString> target)876 public void readBytesList(List<ByteString> target) throws IOException { 877 if (WireFormat.getTagWireType(tag) != WIRETYPE_LENGTH_DELIMITED) { 878 throw InvalidProtocolBufferException.invalidWireType(); 879 } 880 881 while (true) { 882 target.add(readBytes()); 883 if (input.isAtEnd()) { 884 return; 885 } 886 int nextTag = input.readTag(); 887 if (nextTag != tag) { 888 // We've reached the end of the repeated field. Save the next tag value. 889 this.nextTag = nextTag; 890 return; 891 } 892 } 893 } 894 895 @Override readUInt32List(List<Integer> target)896 public void readUInt32List(List<Integer> target) throws IOException { 897 if (target instanceof IntArrayList) { 898 IntArrayList plist = (IntArrayList) target; 899 switch (WireFormat.getTagWireType(tag)) { 900 case WIRETYPE_LENGTH_DELIMITED: 901 final int bytes = input.readUInt32(); 902 int endPos = input.getTotalBytesRead() + bytes; 903 do { 904 plist.addInt(input.readUInt32()); 905 } while (input.getTotalBytesRead() < endPos); 906 requirePosition(endPos); 907 break; 908 case WIRETYPE_VARINT: 909 while (true) { 910 plist.addInt(input.readUInt32()); 911 if (input.isAtEnd()) { 912 return; 913 } 914 int nextTag = input.readTag(); 915 if (nextTag != tag) { 916 // We've reached the end of the repeated field. Save the next tag value. 917 this.nextTag = nextTag; 918 return; 919 } 920 } 921 default: 922 throw InvalidProtocolBufferException.invalidWireType(); 923 } 924 } else { 925 switch (WireFormat.getTagWireType(tag)) { 926 case WIRETYPE_LENGTH_DELIMITED: 927 final int bytes = input.readUInt32(); 928 int endPos = input.getTotalBytesRead() + bytes; 929 do { 930 target.add(input.readUInt32()); 931 } while (input.getTotalBytesRead() < endPos); 932 requirePosition(endPos); 933 break; 934 case WIRETYPE_VARINT: 935 while (true) { 936 target.add(input.readUInt32()); 937 if (input.isAtEnd()) { 938 return; 939 } 940 int nextTag = input.readTag(); 941 if (nextTag != tag) { 942 // We've reached the end of the repeated field. Save the next tag value. 943 this.nextTag = nextTag; 944 return; 945 } 946 } 947 default: 948 throw InvalidProtocolBufferException.invalidWireType(); 949 } 950 } 951 } 952 953 @Override readEnumList(List<Integer> target)954 public void readEnumList(List<Integer> target) throws IOException { 955 if (target instanceof IntArrayList) { 956 IntArrayList plist = (IntArrayList) target; 957 switch (WireFormat.getTagWireType(tag)) { 958 case WIRETYPE_LENGTH_DELIMITED: 959 final int bytes = input.readUInt32(); 960 int endPos = input.getTotalBytesRead() + bytes; 961 do { 962 plist.addInt(input.readEnum()); 963 } while (input.getTotalBytesRead() < endPos); 964 requirePosition(endPos); 965 break; 966 case WIRETYPE_VARINT: 967 while (true) { 968 plist.addInt(input.readEnum()); 969 if (input.isAtEnd()) { 970 return; 971 } 972 int nextTag = input.readTag(); 973 if (nextTag != tag) { 974 // We've reached the end of the repeated field. Save the next tag value. 975 this.nextTag = nextTag; 976 return; 977 } 978 } 979 default: 980 throw InvalidProtocolBufferException.invalidWireType(); 981 } 982 } else { 983 switch (WireFormat.getTagWireType(tag)) { 984 case WIRETYPE_LENGTH_DELIMITED: 985 final int bytes = input.readUInt32(); 986 int endPos = input.getTotalBytesRead() + bytes; 987 do { 988 target.add(input.readEnum()); 989 } while (input.getTotalBytesRead() < endPos); 990 requirePosition(endPos); 991 break; 992 case WIRETYPE_VARINT: 993 while (true) { 994 target.add(input.readEnum()); 995 if (input.isAtEnd()) { 996 return; 997 } 998 int nextTag = input.readTag(); 999 if (nextTag != tag) { 1000 // We've reached the end of the repeated field. Save the next tag value. 1001 this.nextTag = nextTag; 1002 return; 1003 } 1004 } 1005 default: 1006 throw InvalidProtocolBufferException.invalidWireType(); 1007 } 1008 } 1009 } 1010 1011 @Override readSFixed32List(List<Integer> target)1012 public void readSFixed32List(List<Integer> target) throws IOException { 1013 if (target instanceof IntArrayList) { 1014 IntArrayList plist = (IntArrayList) target; 1015 switch (WireFormat.getTagWireType(tag)) { 1016 case WIRETYPE_LENGTH_DELIMITED: 1017 final int bytes = input.readUInt32(); 1018 verifyPackedFixed32Length(bytes); 1019 int endPos = input.getTotalBytesRead() + bytes; 1020 do { 1021 plist.addInt(input.readSFixed32()); 1022 } while (input.getTotalBytesRead() < endPos); 1023 break; 1024 case WIRETYPE_FIXED32: 1025 while (true) { 1026 plist.addInt(input.readSFixed32()); 1027 if (input.isAtEnd()) { 1028 return; 1029 } 1030 int nextTag = input.readTag(); 1031 if (nextTag != tag) { 1032 // We've reached the end of the repeated field. Save the next tag value. 1033 this.nextTag = nextTag; 1034 return; 1035 } 1036 } 1037 default: 1038 throw InvalidProtocolBufferException.invalidWireType(); 1039 } 1040 } else { 1041 switch (WireFormat.getTagWireType(tag)) { 1042 case WIRETYPE_LENGTH_DELIMITED: 1043 final int bytes = input.readUInt32(); 1044 verifyPackedFixed32Length(bytes); 1045 int endPos = input.getTotalBytesRead() + bytes; 1046 do { 1047 target.add(input.readSFixed32()); 1048 } while (input.getTotalBytesRead() < endPos); 1049 break; 1050 case WIRETYPE_FIXED32: 1051 while (true) { 1052 target.add(input.readSFixed32()); 1053 if (input.isAtEnd()) { 1054 return; 1055 } 1056 int nextTag = input.readTag(); 1057 if (nextTag != tag) { 1058 // We've reached the end of the repeated field. Save the next tag value. 1059 this.nextTag = nextTag; 1060 return; 1061 } 1062 } 1063 default: 1064 throw InvalidProtocolBufferException.invalidWireType(); 1065 } 1066 } 1067 } 1068 1069 @Override readSFixed64List(List<Long> target)1070 public void readSFixed64List(List<Long> target) throws IOException { 1071 if (target instanceof LongArrayList) { 1072 LongArrayList plist = (LongArrayList) target; 1073 switch (WireFormat.getTagWireType(tag)) { 1074 case WIRETYPE_LENGTH_DELIMITED: 1075 final int bytes = input.readUInt32(); 1076 verifyPackedFixed64Length(bytes); 1077 int endPos = input.getTotalBytesRead() + bytes; 1078 do { 1079 plist.addLong(input.readSFixed64()); 1080 } while (input.getTotalBytesRead() < endPos); 1081 break; 1082 case WIRETYPE_FIXED64: 1083 while (true) { 1084 plist.addLong(input.readSFixed64()); 1085 if (input.isAtEnd()) { 1086 return; 1087 } 1088 int nextTag = input.readTag(); 1089 if (nextTag != tag) { 1090 // We've reached the end of the repeated field. Save the next tag value. 1091 this.nextTag = nextTag; 1092 return; 1093 } 1094 } 1095 default: 1096 throw InvalidProtocolBufferException.invalidWireType(); 1097 } 1098 } else { 1099 switch (WireFormat.getTagWireType(tag)) { 1100 case WIRETYPE_LENGTH_DELIMITED: 1101 final int bytes = input.readUInt32(); 1102 verifyPackedFixed64Length(bytes); 1103 int endPos = input.getTotalBytesRead() + bytes; 1104 do { 1105 target.add(input.readSFixed64()); 1106 } while (input.getTotalBytesRead() < endPos); 1107 break; 1108 case WIRETYPE_FIXED64: 1109 while (true) { 1110 target.add(input.readSFixed64()); 1111 if (input.isAtEnd()) { 1112 return; 1113 } 1114 int nextTag = input.readTag(); 1115 if (nextTag != tag) { 1116 // We've reached the end of the repeated field. Save the next tag value. 1117 this.nextTag = nextTag; 1118 return; 1119 } 1120 } 1121 default: 1122 throw InvalidProtocolBufferException.invalidWireType(); 1123 } 1124 } 1125 } 1126 1127 @Override readSInt32List(List<Integer> target)1128 public void readSInt32List(List<Integer> target) throws IOException { 1129 if (target instanceof IntArrayList) { 1130 IntArrayList plist = (IntArrayList) target; 1131 switch (WireFormat.getTagWireType(tag)) { 1132 case WIRETYPE_LENGTH_DELIMITED: 1133 final int bytes = input.readUInt32(); 1134 int endPos = input.getTotalBytesRead() + bytes; 1135 do { 1136 plist.addInt(input.readSInt32()); 1137 } while (input.getTotalBytesRead() < endPos); 1138 requirePosition(endPos); 1139 break; 1140 case WIRETYPE_VARINT: 1141 while (true) { 1142 plist.addInt(input.readSInt32()); 1143 if (input.isAtEnd()) { 1144 return; 1145 } 1146 int nextTag = input.readTag(); 1147 if (nextTag != tag) { 1148 // We've reached the end of the repeated field. Save the next tag value. 1149 this.nextTag = nextTag; 1150 return; 1151 } 1152 } 1153 default: 1154 throw InvalidProtocolBufferException.invalidWireType(); 1155 } 1156 } else { 1157 switch (WireFormat.getTagWireType(tag)) { 1158 case WIRETYPE_LENGTH_DELIMITED: 1159 final int bytes = input.readUInt32(); 1160 int endPos = input.getTotalBytesRead() + bytes; 1161 do { 1162 target.add(input.readSInt32()); 1163 } while (input.getTotalBytesRead() < endPos); 1164 requirePosition(endPos); 1165 break; 1166 case WIRETYPE_VARINT: 1167 while (true) { 1168 target.add(input.readSInt32()); 1169 if (input.isAtEnd()) { 1170 return; 1171 } 1172 int nextTag = input.readTag(); 1173 if (nextTag != tag) { 1174 // We've reached the end of the repeated field. Save the next tag value. 1175 this.nextTag = nextTag; 1176 return; 1177 } 1178 } 1179 default: 1180 throw InvalidProtocolBufferException.invalidWireType(); 1181 } 1182 } 1183 } 1184 1185 @Override readSInt64List(List<Long> target)1186 public void readSInt64List(List<Long> target) throws IOException { 1187 if (target instanceof LongArrayList) { 1188 LongArrayList plist = (LongArrayList) target; 1189 switch (WireFormat.getTagWireType(tag)) { 1190 case WIRETYPE_LENGTH_DELIMITED: 1191 final int bytes = input.readUInt32(); 1192 int endPos = input.getTotalBytesRead() + bytes; 1193 do { 1194 plist.addLong(input.readSInt64()); 1195 } while (input.getTotalBytesRead() < endPos); 1196 requirePosition(endPos); 1197 break; 1198 case WIRETYPE_VARINT: 1199 while (true) { 1200 plist.addLong(input.readSInt64()); 1201 if (input.isAtEnd()) { 1202 return; 1203 } 1204 int nextTag = input.readTag(); 1205 if (nextTag != tag) { 1206 // We've reached the end of the repeated field. Save the next tag value. 1207 this.nextTag = nextTag; 1208 return; 1209 } 1210 } 1211 default: 1212 throw InvalidProtocolBufferException.invalidWireType(); 1213 } 1214 } else { 1215 switch (WireFormat.getTagWireType(tag)) { 1216 case WIRETYPE_LENGTH_DELIMITED: 1217 final int bytes = input.readUInt32(); 1218 int endPos = input.getTotalBytesRead() + bytes; 1219 do { 1220 target.add(input.readSInt64()); 1221 } while (input.getTotalBytesRead() < endPos); 1222 requirePosition(endPos); 1223 break; 1224 case WIRETYPE_VARINT: 1225 while (true) { 1226 target.add(input.readSInt64()); 1227 if (input.isAtEnd()) { 1228 return; 1229 } 1230 int nextTag = input.readTag(); 1231 if (nextTag != tag) { 1232 // We've reached the end of the repeated field. Save the next tag value. 1233 this.nextTag = nextTag; 1234 return; 1235 } 1236 } 1237 default: 1238 throw InvalidProtocolBufferException.invalidWireType(); 1239 } 1240 } 1241 } 1242 verifyPackedFixed64Length(int bytes)1243 private void verifyPackedFixed64Length(int bytes) throws IOException { 1244 if ((bytes & FIXED64_MULTIPLE_MASK) != 0) { 1245 // Require that the number of bytes be a multiple of 8. 1246 throw InvalidProtocolBufferException.parseFailure(); 1247 } 1248 } 1249 1250 @SuppressWarnings("unchecked") 1251 @Override readMap( Map<K, V> target, MapEntryLite.Metadata<K, V> metadata, ExtensionRegistryLite extensionRegistry)1252 public <K, V> void readMap( 1253 Map<K, V> target, 1254 MapEntryLite.Metadata<K, V> metadata, 1255 ExtensionRegistryLite extensionRegistry) 1256 throws IOException { 1257 requireWireType(WIRETYPE_LENGTH_DELIMITED); 1258 int size = input.readUInt32(); 1259 final int prevLimit = input.pushLimit(size); 1260 K key = metadata.defaultKey; 1261 V value = metadata.defaultValue; 1262 try { 1263 while (true) { 1264 int number = getFieldNumber(); 1265 if (number == READ_DONE || input.isAtEnd()) { 1266 break; 1267 } 1268 try { 1269 switch (number) { 1270 case 1: 1271 key = (K) readField(metadata.keyType, null, null); 1272 break; 1273 case 2: 1274 value = 1275 (V) 1276 readField( 1277 metadata.valueType, metadata.defaultValue.getClass(), extensionRegistry); 1278 break; 1279 default: 1280 if (!skipField()) { 1281 throw new InvalidProtocolBufferException("Unable to parse map entry."); 1282 } 1283 break; 1284 } 1285 } catch (InvalidProtocolBufferException.InvalidWireTypeException ignore) { 1286 // the type doesn't match, skip the field. 1287 if (!skipField()) { 1288 throw new InvalidProtocolBufferException("Unable to parse map entry."); 1289 } 1290 } 1291 } 1292 target.put(key, value); 1293 } finally { 1294 // Restore the previous limit. 1295 input.popLimit(prevLimit); 1296 } 1297 } 1298 readField( WireFormat.FieldType fieldType, Class<?> messageType, ExtensionRegistryLite extensionRegistry)1299 private Object readField( 1300 WireFormat.FieldType fieldType, Class<?> messageType, ExtensionRegistryLite extensionRegistry) 1301 throws IOException { 1302 switch (fieldType) { 1303 case BOOL: 1304 return readBool(); 1305 case BYTES: 1306 return readBytes(); 1307 case DOUBLE: 1308 return readDouble(); 1309 case ENUM: 1310 return readEnum(); 1311 case FIXED32: 1312 return readFixed32(); 1313 case FIXED64: 1314 return readFixed64(); 1315 case FLOAT: 1316 return readFloat(); 1317 case INT32: 1318 return readInt32(); 1319 case INT64: 1320 return readInt64(); 1321 case MESSAGE: 1322 return readMessage(messageType, extensionRegistry); 1323 case SFIXED32: 1324 return readSFixed32(); 1325 case SFIXED64: 1326 return readSFixed64(); 1327 case SINT32: 1328 return readSInt32(); 1329 case SINT64: 1330 return readSInt64(); 1331 case STRING: 1332 return readStringRequireUtf8(); 1333 case UINT32: 1334 return readUInt32(); 1335 case UINT64: 1336 return readUInt64(); 1337 default: 1338 throw new RuntimeException("unsupported field type."); 1339 } 1340 } 1341 verifyPackedFixed32Length(int bytes)1342 private void verifyPackedFixed32Length(int bytes) throws IOException { 1343 if ((bytes & FIXED32_MULTIPLE_MASK) != 0) { 1344 // Require that the number of bytes be a multiple of 4. 1345 throw InvalidProtocolBufferException.parseFailure(); 1346 } 1347 } 1348 requirePosition(int expectedPosition)1349 private void requirePosition(int expectedPosition) throws IOException { 1350 if (input.getTotalBytesRead() != expectedPosition) { 1351 throw InvalidProtocolBufferException.truncatedMessage(); 1352 } 1353 } 1354 } 1355