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