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 com.google.protobuf.Descriptors.FieldDescriptor; 34 35 import java.io.IOException; 36 import java.util.ArrayList; 37 import java.util.List; 38 import java.util.Map; 39 import java.util.TreeMap; 40 41 /** 42 * Reflection utility methods shared by both mutable and immutable messages. 43 * 44 * @author liujisi (at) google.com (Pherl Liu) 45 */ 46 class MessageReflection { 47 48 static void writeMessageTo(Message message, CodedOutputStream output, 49 boolean alwaysWriteRequiredFields) 50 throws IOException { 51 final boolean isMessageSet = 52 message.getDescriptorForType().getOptions().getMessageSetWireFormat(); 53 54 Map<FieldDescriptor, Object> fields = message.getAllFields(); 55 if (alwaysWriteRequiredFields) { 56 fields = new TreeMap<FieldDescriptor, Object>(fields); 57 for (final FieldDescriptor field : 58 message.getDescriptorForType().getFields()) { 59 if (field.isRequired() && !fields.containsKey(field)) { 60 fields.put(field, message.getField(field)); 61 } 62 } 63 } 64 for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry : 65 fields.entrySet()) { 66 final Descriptors.FieldDescriptor field = entry.getKey(); 67 final Object value = entry.getValue(); 68 if (isMessageSet && field.isExtension() && 69 field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE && 70 !field.isRepeated()) { 71 output.writeMessageSetExtension(field.getNumber(), (Message) value); 72 } else { 73 FieldSet.writeField(field, value, output); 74 } 75 } 76 77 final UnknownFieldSet unknownFields = message.getUnknownFields(); 78 if (isMessageSet) { 79 unknownFields.writeAsMessageSetTo(output); 80 } else { 81 unknownFields.writeTo(output); 82 } 83 } 84 85 static int getSerializedSize(Message message) { 86 int size = 0; 87 final boolean isMessageSet = 88 message.getDescriptorForType().getOptions().getMessageSetWireFormat(); 89 90 for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry : 91 message.getAllFields().entrySet()) { 92 final Descriptors.FieldDescriptor field = entry.getKey(); 93 final Object value = entry.getValue(); 94 if (isMessageSet && field.isExtension() && 95 field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE && 96 !field.isRepeated()) { 97 size += CodedOutputStream.computeMessageSetExtensionSize( 98 field.getNumber(), (Message) value); 99 } else { 100 size += FieldSet.computeFieldSize(field, value); 101 } 102 } 103 104 final UnknownFieldSet unknownFields = message.getUnknownFields(); 105 if (isMessageSet) { 106 size += unknownFields.getSerializedSizeAsMessageSet(); 107 } else { 108 size += unknownFields.getSerializedSize(); 109 } 110 return size; 111 } 112 113 static String delimitWithCommas(List<String> parts) { 114 StringBuilder result = new StringBuilder(); 115 for (String part : parts) { 116 if (result.length() > 0) { 117 result.append(", "); 118 } 119 result.append(part); 120 } 121 return result.toString(); 122 } 123 124 @SuppressWarnings("unchecked") 125 static boolean isInitialized(MessageOrBuilder message) { 126 // Check that all required fields are present. 127 for (final Descriptors.FieldDescriptor field : message 128 .getDescriptorForType() 129 .getFields()) { 130 if (field.isRequired()) { 131 if (!message.hasField(field)) { 132 return false; 133 } 134 } 135 } 136 137 // Check that embedded messages are initialized. 138 for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry : 139 message.getAllFields().entrySet()) { 140 final Descriptors.FieldDescriptor field = entry.getKey(); 141 if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) { 142 if (field.isRepeated()) { 143 for (final Message element 144 : (List<Message>) entry.getValue()) { 145 if (!element.isInitialized()) { 146 return false; 147 } 148 } 149 } else { 150 if (!((Message) entry.getValue()).isInitialized()) { 151 return false; 152 } 153 } 154 } 155 } 156 157 return true; 158 } 159 160 private static String subMessagePrefix(final String prefix, 161 final Descriptors.FieldDescriptor field, 162 final int index) { 163 final StringBuilder result = new StringBuilder(prefix); 164 if (field.isExtension()) { 165 result.append('(') 166 .append(field.getFullName()) 167 .append(')'); 168 } else { 169 result.append(field.getName()); 170 } 171 if (index != -1) { 172 result.append('[') 173 .append(index) 174 .append(']'); 175 } 176 result.append('.'); 177 return result.toString(); 178 } 179 180 private static void findMissingFields(final MessageOrBuilder message, 181 final String prefix, 182 final List<String> results) { 183 for (final Descriptors.FieldDescriptor field : 184 message.getDescriptorForType().getFields()) { 185 if (field.isRequired() && !message.hasField(field)) { 186 results.add(prefix + field.getName()); 187 } 188 } 189 190 for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry : 191 message.getAllFields().entrySet()) { 192 final Descriptors.FieldDescriptor field = entry.getKey(); 193 final Object value = entry.getValue(); 194 195 if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) { 196 if (field.isRepeated()) { 197 int i = 0; 198 for (final Object element : (List) value) { 199 findMissingFields((MessageOrBuilder) element, 200 subMessagePrefix(prefix, field, i++), 201 results); 202 } 203 } else { 204 if (message.hasField(field)) { 205 findMissingFields((MessageOrBuilder) value, 206 subMessagePrefix(prefix, field, -1), 207 results); 208 } 209 } 210 } 211 } 212 } 213 214 /** 215 * Populates {@code this.missingFields} with the full "path" of each missing 216 * required field in the given message. 217 */ 218 static List<String> findMissingFields( 219 final MessageOrBuilder message) { 220 final List<String> results = new ArrayList<String>(); 221 findMissingFields(message, "", results); 222 return results; 223 } 224 225 static interface MergeTarget { 226 enum ContainerType { 227 MESSAGE, EXTENSION_SET 228 } 229 230 /** 231 * Returns the descriptor for the target. 232 */ 233 public Descriptors.Descriptor getDescriptorForType(); 234 235 public ContainerType getContainerType(); 236 237 public ExtensionRegistry.ExtensionInfo findExtensionByName( 238 ExtensionRegistry registry, String name); 239 240 public ExtensionRegistry.ExtensionInfo findExtensionByNumber( 241 ExtensionRegistry registry, Descriptors.Descriptor containingType, 242 int fieldNumber); 243 244 /** 245 * Obtains the value of the given field, or the default value if it is not 246 * set. For primitive fields, the boxed primitive value is returned. For 247 * enum fields, the EnumValueDescriptor for the value is returned. For 248 * embedded message fields, the sub-message is returned. For repeated 249 * fields, a java.util.List is returned. 250 */ 251 public Object getField(Descriptors.FieldDescriptor field); 252 253 /** 254 * Returns true if the given field is set. This is exactly equivalent to 255 * calling the generated "has" accessor method corresponding to the field. 256 * 257 * @throws IllegalArgumentException The field is a repeated field, or {@code 258 * field.getContainingType() != getDescriptorForType()}. 259 */ 260 boolean hasField(Descriptors.FieldDescriptor field); 261 262 /** 263 * Sets a field to the given value. The value must be of the correct type 264 * for this field, i.e. the same type that 265 * {@link Message#getField(Descriptors.FieldDescriptor)} 266 * would return. 267 */ 268 MergeTarget setField(Descriptors.FieldDescriptor field, Object value); 269 270 /** 271 * Clears the field. This is exactly equivalent to calling the generated 272 * "clear" accessor method corresponding to the field. 273 */ 274 MergeTarget clearField(Descriptors.FieldDescriptor field); 275 276 /** 277 * Sets an element of a repeated field to the given value. The value must 278 * be of the correct type for this field, i.e. the same type that {@link 279 * Message#getRepeatedField(Descriptors.FieldDescriptor, int)} would return. 280 * 281 * @throws IllegalArgumentException The field is not a repeated field, or 282 * {@code field.getContainingType() != 283 * getDescriptorForType()}. 284 */ 285 MergeTarget setRepeatedField(Descriptors.FieldDescriptor field, 286 int index, Object value); 287 288 /** 289 * Like {@code setRepeatedField}, but appends the value as a new element. 290 * 291 * @throws IllegalArgumentException The field is not a repeated field, or 292 * {@code field.getContainingType() != 293 * getDescriptorForType()}. 294 */ 295 MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, 296 Object value); 297 298 /** 299 * Returns true if the given oneof is set. 300 * 301 * @throws IllegalArgumentException if 302 * {@code oneof.getContainingType() != getDescriptorForType()}. 303 */ 304 boolean hasOneof(Descriptors.OneofDescriptor oneof); 305 306 /** 307 * Clears the oneof. This is exactly equivalent to calling the generated 308 * "clear" accessor method corresponding to the oneof. 309 */ 310 MergeTarget clearOneof(Descriptors.OneofDescriptor oneof); 311 312 /** 313 * Obtains the FieldDescriptor if the given oneof is set. Returns null 314 * if no field is set. 315 */ 316 Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof); 317 318 /** 319 * Parse the input stream into a sub field group defined based on either 320 * FieldDescriptor or the default instance. 321 */ 322 Object parseGroup(CodedInputStream input, ExtensionRegistryLite registry, 323 Descriptors.FieldDescriptor descriptor, Message defaultInstance) 324 throws IOException; 325 326 /** 327 * Parse the input stream into a sub field message defined based on either 328 * FieldDescriptor or the default instance. 329 */ 330 Object parseMessage(CodedInputStream input, ExtensionRegistryLite registry, 331 Descriptors.FieldDescriptor descriptor, Message defaultInstance) 332 throws IOException; 333 334 /** 335 * Parse from a ByteString into a sub field message defined based on either 336 * FieldDescriptor or the default instance. There isn't a varint indicating 337 * the length of the message at the beginning of the input ByteString. 338 */ 339 Object parseMessageFromBytes( 340 ByteString bytes, ExtensionRegistryLite registry, 341 Descriptors.FieldDescriptor descriptor, Message defaultInstance) 342 throws IOException; 343 344 /** 345 * Read a primitive field from input. Note that builders and mutable 346 * messages may use different Java types to represent a primtive field. 347 */ 348 Object readPrimitiveField( 349 CodedInputStream input, WireFormat.FieldType type, 350 boolean checkUtf8) throws IOException; 351 352 /** 353 * Returns a new merge target for a sub-field. When defaultInstance is 354 * provided, it indicates the descriptor is for an extension type, and 355 * implementations should create a new instance from the defaultInstance 356 * prototype directly. 357 */ 358 MergeTarget newMergeTargetForField( 359 Descriptors.FieldDescriptor descriptor, 360 Message defaultInstance); 361 362 /** 363 * Finishes the merge and returns the underlying object. 364 */ 365 Object finish(); 366 } 367 368 static class BuilderAdapter implements MergeTarget { 369 370 private final Message.Builder builder; 371 372 public Descriptors.Descriptor getDescriptorForType() { 373 return builder.getDescriptorForType(); 374 } 375 376 public BuilderAdapter(Message.Builder builder) { 377 this.builder = builder; 378 } 379 380 public Object getField(Descriptors.FieldDescriptor field) { 381 return builder.getField(field); 382 } 383 384 @Override 385 public boolean hasField(Descriptors.FieldDescriptor field) { 386 return builder.hasField(field); 387 } 388 389 public MergeTarget setField(Descriptors.FieldDescriptor field, 390 Object value) { 391 builder.setField(field, value); 392 return this; 393 } 394 395 public MergeTarget clearField(Descriptors.FieldDescriptor field) { 396 builder.clearField(field); 397 return this; 398 } 399 400 public MergeTarget setRepeatedField( 401 Descriptors.FieldDescriptor field, int index, Object value) { 402 builder.setRepeatedField(field, index, value); 403 return this; 404 } 405 406 public MergeTarget addRepeatedField( 407 Descriptors.FieldDescriptor field, Object value) { 408 builder.addRepeatedField(field, value); 409 return this; 410 } 411 412 @Override 413 public boolean hasOneof(Descriptors.OneofDescriptor oneof) { 414 return builder.hasOneof(oneof); 415 } 416 417 @Override 418 public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) { 419 builder.clearOneof(oneof); 420 return this; 421 } 422 423 @Override 424 public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) { 425 return builder.getOneofFieldDescriptor(oneof); 426 } 427 428 public ContainerType getContainerType() { 429 return ContainerType.MESSAGE; 430 } 431 432 public ExtensionRegistry.ExtensionInfo findExtensionByName( 433 ExtensionRegistry registry, String name) { 434 return registry.findImmutableExtensionByName(name); 435 } 436 437 public ExtensionRegistry.ExtensionInfo findExtensionByNumber( 438 ExtensionRegistry registry, Descriptors.Descriptor containingType, 439 int fieldNumber) { 440 return registry.findImmutableExtensionByNumber(containingType, 441 fieldNumber); 442 } 443 444 public Object parseGroup(CodedInputStream input, 445 ExtensionRegistryLite extensionRegistry, 446 Descriptors.FieldDescriptor field, Message defaultInstance) 447 throws IOException { 448 Message.Builder subBuilder; 449 // When default instance is not null. The field is an extension field. 450 if (defaultInstance != null) { 451 subBuilder = defaultInstance.newBuilderForType(); 452 } else { 453 subBuilder = builder.newBuilderForField(field); 454 } 455 if (!field.isRepeated()) { 456 Message originalMessage = (Message) getField(field); 457 if (originalMessage != null) { 458 subBuilder.mergeFrom(originalMessage); 459 } 460 } 461 input.readGroup(field.getNumber(), subBuilder, extensionRegistry); 462 return subBuilder.buildPartial(); 463 } 464 465 public Object parseMessage(CodedInputStream input, 466 ExtensionRegistryLite extensionRegistry, 467 Descriptors.FieldDescriptor field, Message defaultInstance) 468 throws IOException { 469 Message.Builder subBuilder; 470 // When default instance is not null. The field is an extension field. 471 if (defaultInstance != null) { 472 subBuilder = defaultInstance.newBuilderForType(); 473 } else { 474 subBuilder = builder.newBuilderForField(field); 475 } 476 if (!field.isRepeated()) { 477 Message originalMessage = (Message) getField(field); 478 if (originalMessage != null) { 479 subBuilder.mergeFrom(originalMessage); 480 } 481 } 482 input.readMessage(subBuilder, extensionRegistry); 483 return subBuilder.buildPartial(); 484 } 485 486 public Object parseMessageFromBytes(ByteString bytes, 487 ExtensionRegistryLite extensionRegistry, 488 Descriptors.FieldDescriptor field, Message defaultInstance) 489 throws IOException { 490 Message.Builder subBuilder; 491 // When default instance is not null. The field is an extension field. 492 if (defaultInstance != null) { 493 subBuilder = defaultInstance.newBuilderForType(); 494 } else { 495 subBuilder = builder.newBuilderForField(field); 496 } 497 if (!field.isRepeated()) { 498 Message originalMessage = (Message) getField(field); 499 if (originalMessage != null) { 500 subBuilder.mergeFrom(originalMessage); 501 } 502 } 503 subBuilder.mergeFrom(bytes, extensionRegistry); 504 return subBuilder.buildPartial(); 505 } 506 507 public MergeTarget newMergeTargetForField(Descriptors.FieldDescriptor field, 508 Message defaultInstance) { 509 if (defaultInstance != null) { 510 return new BuilderAdapter( 511 defaultInstance.newBuilderForType()); 512 } else { 513 return new BuilderAdapter(builder.newBuilderForField(field)); 514 } 515 } 516 517 public Object readPrimitiveField( 518 CodedInputStream input, WireFormat.FieldType type, 519 boolean checkUtf8) throws IOException { 520 return FieldSet.readPrimitiveField(input, type, checkUtf8); 521 } 522 523 public Object finish() { 524 return builder.buildPartial(); 525 } 526 } 527 528 529 static class ExtensionAdapter implements MergeTarget { 530 531 private final FieldSet<Descriptors.FieldDescriptor> extensions; 532 533 ExtensionAdapter(FieldSet<Descriptors.FieldDescriptor> extensions) { 534 this.extensions = extensions; 535 } 536 537 public Descriptors.Descriptor getDescriptorForType() { 538 throw new UnsupportedOperationException( 539 "getDescriptorForType() called on FieldSet object"); 540 } 541 542 public Object getField(Descriptors.FieldDescriptor field) { 543 return extensions.getField(field); 544 } 545 546 public boolean hasField(Descriptors.FieldDescriptor field) { 547 return extensions.hasField(field); 548 } 549 550 public MergeTarget setField(Descriptors.FieldDescriptor field, 551 Object value) { 552 extensions.setField(field, value); 553 return this; 554 } 555 556 public MergeTarget clearField(Descriptors.FieldDescriptor field) { 557 extensions.clearField(field); 558 return this; 559 } 560 561 public MergeTarget setRepeatedField( 562 Descriptors.FieldDescriptor field, int index, Object value) { 563 extensions.setRepeatedField(field, index, value); 564 return this; 565 } 566 567 public MergeTarget addRepeatedField( 568 Descriptors.FieldDescriptor field, Object value) { 569 extensions.addRepeatedField(field, value); 570 return this; 571 } 572 573 @Override 574 public boolean hasOneof(Descriptors.OneofDescriptor oneof) { 575 return false; 576 } 577 578 @Override 579 public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) { 580 // Nothing to clear. 581 return this; 582 } 583 584 @Override 585 public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) { 586 return null; 587 } 588 589 public ContainerType getContainerType() { 590 return ContainerType.EXTENSION_SET; 591 } 592 593 public ExtensionRegistry.ExtensionInfo findExtensionByName( 594 ExtensionRegistry registry, String name) { 595 return registry.findImmutableExtensionByName(name); 596 } 597 598 public ExtensionRegistry.ExtensionInfo findExtensionByNumber( 599 ExtensionRegistry registry, Descriptors.Descriptor containingType, 600 int fieldNumber) { 601 return registry.findImmutableExtensionByNumber(containingType, 602 fieldNumber); 603 } 604 605 public Object parseGroup(CodedInputStream input, 606 ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, 607 Message defaultInstance) throws IOException { 608 Message.Builder subBuilder = 609 defaultInstance.newBuilderForType(); 610 if (!field.isRepeated()) { 611 Message originalMessage = (Message) getField(field); 612 if (originalMessage != null) { 613 subBuilder.mergeFrom(originalMessage); 614 } 615 } 616 input.readGroup(field.getNumber(), subBuilder, registry); 617 return subBuilder.buildPartial(); 618 } 619 620 public Object parseMessage(CodedInputStream input, 621 ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, 622 Message defaultInstance) throws IOException { 623 Message.Builder subBuilder = 624 defaultInstance.newBuilderForType(); 625 if (!field.isRepeated()) { 626 Message originalMessage = (Message) getField(field); 627 if (originalMessage != null) { 628 subBuilder.mergeFrom(originalMessage); 629 } 630 } 631 input.readMessage(subBuilder, registry); 632 return subBuilder.buildPartial(); 633 } 634 635 public Object parseMessageFromBytes(ByteString bytes, 636 ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, 637 Message defaultInstance) throws IOException { 638 Message.Builder subBuilder = defaultInstance.newBuilderForType(); 639 if (!field.isRepeated()) { 640 Message originalMessage = (Message) getField(field); 641 if (originalMessage != null) { 642 subBuilder.mergeFrom(originalMessage); 643 } 644 } 645 subBuilder.mergeFrom(bytes, registry); 646 return subBuilder.buildPartial(); 647 } 648 649 public MergeTarget newMergeTargetForField( 650 Descriptors.FieldDescriptor descriptor, Message defaultInstance) { 651 throw new UnsupportedOperationException( 652 "newMergeTargetForField() called on FieldSet object"); 653 } 654 655 public Object readPrimitiveField( 656 CodedInputStream input, WireFormat.FieldType type, 657 boolean checkUtf8) throws IOException { 658 return FieldSet.readPrimitiveField(input, type, checkUtf8); 659 } 660 661 public Object finish() { 662 throw new UnsupportedOperationException( 663 "finish() called on FieldSet object"); 664 } 665 } 666 667 /** 668 * Parses a single field into MergeTarget. The target can be Message.Builder, 669 * FieldSet or MutableMessage. 670 * 671 * Package-private because it is used by GeneratedMessage.ExtendableMessage. 672 * 673 * @param tag The tag, which should have already been read. 674 * @return {@code true} unless the tag is an end-group tag. 675 */ 676 static boolean mergeFieldFrom( 677 CodedInputStream input, 678 UnknownFieldSet.Builder unknownFields, 679 ExtensionRegistryLite extensionRegistry, 680 Descriptors.Descriptor type, 681 MergeTarget target, 682 int tag) throws IOException { 683 if (type.getOptions().getMessageSetWireFormat() && 684 tag == WireFormat.MESSAGE_SET_ITEM_TAG) { 685 mergeMessageSetExtensionFromCodedStream( 686 input, unknownFields, extensionRegistry, type, target); 687 return true; 688 } 689 690 final int wireType = WireFormat.getTagWireType(tag); 691 final int fieldNumber = WireFormat.getTagFieldNumber(tag); 692 693 final Descriptors.FieldDescriptor field; 694 Message defaultInstance = null; 695 696 if (type.isExtensionNumber(fieldNumber)) { 697 // extensionRegistry may be either ExtensionRegistry or 698 // ExtensionRegistryLite. Since the type we are parsing is a full 699 // message, only a full ExtensionRegistry could possibly contain 700 // extensions of it. Otherwise we will treat the registry as if it 701 // were empty. 702 if (extensionRegistry instanceof ExtensionRegistry) { 703 final ExtensionRegistry.ExtensionInfo extension = 704 target.findExtensionByNumber((ExtensionRegistry) extensionRegistry, 705 type, fieldNumber); 706 if (extension == null) { 707 field = null; 708 } else { 709 field = extension.descriptor; 710 defaultInstance = extension.defaultInstance; 711 if (defaultInstance == null && 712 field.getJavaType() 713 == Descriptors.FieldDescriptor.JavaType.MESSAGE) { 714 throw new IllegalStateException( 715 "Message-typed extension lacked default instance: " + 716 field.getFullName()); 717 } 718 } 719 } else { 720 field = null; 721 } 722 } else if (target.getContainerType() == MergeTarget.ContainerType.MESSAGE) { 723 field = type.findFieldByNumber(fieldNumber); 724 } else { 725 field = null; 726 } 727 728 boolean unknown = false; 729 boolean packed = false; 730 if (field == null) { 731 unknown = true; // Unknown field. 732 } else if (wireType == FieldSet.getWireFormatForFieldType( 733 field.getLiteType(), 734 false /* isPacked */)) { 735 packed = false; 736 } else if (field.isPackable() && 737 wireType == FieldSet.getWireFormatForFieldType( 738 field.getLiteType(), 739 true /* isPacked */)) { 740 packed = true; 741 } else { 742 unknown = true; // Unknown wire type. 743 } 744 745 if (unknown) { // Unknown field or wrong wire type. Skip. 746 return unknownFields.mergeFieldFrom(tag, input); 747 } 748 749 if (packed) { 750 final int length = input.readRawVarint32(); 751 final int limit = input.pushLimit(length); 752 if (field.getLiteType() == WireFormat.FieldType.ENUM) { 753 while (input.getBytesUntilLimit() > 0) { 754 final int rawValue = input.readEnum(); 755 final Object value = field.getEnumType().findValueByNumber(rawValue); 756 if (value == null) { 757 // If the number isn't recognized as a valid value for this 758 // enum, drop it (don't even add it to unknownFields). 759 return true; 760 } 761 target.addRepeatedField(field, value); 762 } 763 } else { 764 while (input.getBytesUntilLimit() > 0) { 765 final Object value = 766 target.readPrimitiveField(input, field.getLiteType(), field.needsUtf8Check()); 767 target.addRepeatedField(field, value); 768 } 769 } 770 input.popLimit(limit); 771 } else { 772 final Object value; 773 switch (field.getType()) { 774 case GROUP: { 775 value = target 776 .parseGroup(input, extensionRegistry, field, defaultInstance); 777 break; 778 } 779 case MESSAGE: { 780 value = target 781 .parseMessage(input, extensionRegistry, field, defaultInstance); 782 break; 783 } 784 case ENUM: 785 final int rawValue = input.readEnum(); 786 value = field.getEnumType().findValueByNumber(rawValue); 787 // If the number isn't recognized as a valid value for this enum, 788 // drop it. 789 if (value == null) { 790 unknownFields.mergeVarintField(fieldNumber, rawValue); 791 return true; 792 } 793 break; 794 default: 795 value = target.readPrimitiveField(input, field.getLiteType(), field.needsUtf8Check()); 796 break; 797 } 798 799 if (field.isRepeated()) { 800 target.addRepeatedField(field, value); 801 } else { 802 target.setField(field, value); 803 } 804 } 805 806 return true; 807 } 808 809 /** 810 * Called by {@code #mergeFieldFrom()} to parse a MessageSet extension into 811 * MergeTarget. 812 */ 813 private static void mergeMessageSetExtensionFromCodedStream( 814 CodedInputStream input, 815 UnknownFieldSet.Builder unknownFields, 816 ExtensionRegistryLite extensionRegistry, 817 Descriptors.Descriptor type, 818 MergeTarget target) throws IOException { 819 820 // The wire format for MessageSet is: 821 // message MessageSet { 822 // repeated group Item = 1 { 823 // required int32 typeId = 2; 824 // required bytes message = 3; 825 // } 826 // } 827 // "typeId" is the extension's field number. The extension can only be 828 // a message type, where "message" contains the encoded bytes of that 829 // message. 830 // 831 // In practice, we will probably never see a MessageSet item in which 832 // the message appears before the type ID, or where either field does not 833 // appear exactly once. However, in theory such cases are valid, so we 834 // should be prepared to accept them. 835 836 int typeId = 0; 837 ByteString rawBytes = null; // If we encounter "message" before "typeId" 838 ExtensionRegistry.ExtensionInfo extension = null; 839 840 // Read bytes from input, if we get it's type first then parse it eagerly, 841 // otherwise we store the raw bytes in a local variable. 842 while (true) { 843 final int tag = input.readTag(); 844 if (tag == 0) { 845 break; 846 } 847 848 if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) { 849 typeId = input.readUInt32(); 850 if (typeId != 0) { 851 // extensionRegistry may be either ExtensionRegistry or 852 // ExtensionRegistryLite. Since the type we are parsing is a full 853 // message, only a full ExtensionRegistry could possibly contain 854 // extensions of it. Otherwise we will treat the registry as if it 855 // were empty. 856 if (extensionRegistry instanceof ExtensionRegistry) { 857 extension = target.findExtensionByNumber( 858 (ExtensionRegistry) extensionRegistry, type, typeId); 859 } 860 } 861 862 } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) { 863 if (typeId != 0) { 864 if (extension != null && 865 ExtensionRegistryLite.isEagerlyParseMessageSets()) { 866 // We already know the type, so we can parse directly from the 867 // input with no copying. Hooray! 868 eagerlyMergeMessageSetExtension( 869 input, extension, extensionRegistry, target); 870 rawBytes = null; 871 continue; 872 } 873 } 874 // We haven't seen a type ID yet or we want parse message lazily. 875 rawBytes = input.readBytes(); 876 877 } else { // Unknown tag. Skip it. 878 if (!input.skipField(tag)) { 879 break; // End of group 880 } 881 } 882 } 883 input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG); 884 885 // Process the raw bytes. 886 if (rawBytes != null && typeId != 0) { // Zero is not a valid type ID. 887 if (extension != null) { // We known the type 888 mergeMessageSetExtensionFromBytes( 889 rawBytes, extension, extensionRegistry, target); 890 } else { // We don't know how to parse this. Ignore it. 891 if (rawBytes != null) { 892 unknownFields.mergeField(typeId, UnknownFieldSet.Field.newBuilder() 893 .addLengthDelimited(rawBytes).build()); 894 } 895 } 896 } 897 } 898 899 private static void mergeMessageSetExtensionFromBytes( 900 ByteString rawBytes, 901 ExtensionRegistry.ExtensionInfo extension, 902 ExtensionRegistryLite extensionRegistry, 903 MergeTarget target) throws IOException { 904 905 Descriptors.FieldDescriptor field = extension.descriptor; 906 boolean hasOriginalValue = target.hasField(field); 907 908 if (hasOriginalValue || ExtensionRegistryLite.isEagerlyParseMessageSets()) { 909 // If the field already exists, we just parse the field. 910 Object value = target.parseMessageFromBytes( 911 rawBytes, extensionRegistry,field, extension.defaultInstance); 912 target.setField(field, value); 913 } else { 914 // Use LazyField to load MessageSet lazily. 915 LazyField lazyField = new LazyField( 916 extension.defaultInstance, extensionRegistry, rawBytes); 917 target.setField(field, lazyField); 918 } 919 } 920 921 private static void eagerlyMergeMessageSetExtension( 922 CodedInputStream input, 923 ExtensionRegistry.ExtensionInfo extension, 924 ExtensionRegistryLite extensionRegistry, 925 MergeTarget target) throws IOException { 926 Descriptors.FieldDescriptor field = extension.descriptor; 927 Object value = target.parseMessage(input, extensionRegistry, field, 928 extension.defaultInstance); 929 target.setField(field, value); 930 } 931 } 932