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