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 370 static class BuilderAdapter implements MergeTarget { 371 372 private final Message.Builder builder; 373 374 @Override getDescriptorForType()375 public Descriptors.Descriptor getDescriptorForType() { 376 return builder.getDescriptorForType(); 377 } 378 BuilderAdapter(Message.Builder builder)379 public BuilderAdapter(Message.Builder builder) { 380 this.builder = builder; 381 } 382 383 @Override getField(Descriptors.FieldDescriptor field)384 public Object getField(Descriptors.FieldDescriptor field) { 385 return builder.getField(field); 386 } 387 388 @Override hasField(Descriptors.FieldDescriptor field)389 public boolean hasField(Descriptors.FieldDescriptor field) { 390 return builder.hasField(field); 391 } 392 393 @Override setField(Descriptors.FieldDescriptor field, Object value)394 public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) { 395 builder.setField(field, value); 396 return this; 397 } 398 399 @Override clearField(Descriptors.FieldDescriptor field)400 public MergeTarget clearField(Descriptors.FieldDescriptor field) { 401 builder.clearField(field); 402 return this; 403 } 404 405 @Override setRepeatedField( Descriptors.FieldDescriptor field, int index, Object value)406 public MergeTarget setRepeatedField( 407 Descriptors.FieldDescriptor field, int index, Object value) { 408 builder.setRepeatedField(field, index, value); 409 return this; 410 } 411 412 @Override addRepeatedField(Descriptors.FieldDescriptor field, Object value)413 public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) { 414 builder.addRepeatedField(field, value); 415 return this; 416 } 417 418 @Override hasOneof(Descriptors.OneofDescriptor oneof)419 public boolean hasOneof(Descriptors.OneofDescriptor oneof) { 420 return builder.hasOneof(oneof); 421 } 422 423 @Override clearOneof(Descriptors.OneofDescriptor oneof)424 public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) { 425 builder.clearOneof(oneof); 426 return this; 427 } 428 429 @Override getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof)430 public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) { 431 return builder.getOneofFieldDescriptor(oneof); 432 } 433 434 @Override getContainerType()435 public ContainerType getContainerType() { 436 return ContainerType.MESSAGE; 437 } 438 439 @Override findExtensionByName( ExtensionRegistry registry, String name)440 public ExtensionRegistry.ExtensionInfo findExtensionByName( 441 ExtensionRegistry registry, String name) { 442 return registry.findImmutableExtensionByName(name); 443 } 444 445 @Override findExtensionByNumber( ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber)446 public ExtensionRegistry.ExtensionInfo findExtensionByNumber( 447 ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) { 448 return registry.findImmutableExtensionByNumber(containingType, 449 fieldNumber); 450 } 451 452 @Override parseGroup( CodedInputStream input, ExtensionRegistryLite extensionRegistry, Descriptors.FieldDescriptor field, Message defaultInstance)453 public Object parseGroup( 454 CodedInputStream input, 455 ExtensionRegistryLite extensionRegistry, 456 Descriptors.FieldDescriptor field, 457 Message defaultInstance) 458 throws IOException { 459 Message.Builder subBuilder; 460 // When default instance is not null. The field is an extension field. 461 if (defaultInstance != null) { 462 subBuilder = defaultInstance.newBuilderForType(); 463 } else { 464 subBuilder = builder.newBuilderForField(field); 465 } 466 if (!field.isRepeated()) { 467 Message originalMessage = (Message) getField(field); 468 if (originalMessage != null) { 469 subBuilder.mergeFrom(originalMessage); 470 } 471 } 472 input.readGroup(field.getNumber(), subBuilder, extensionRegistry); 473 return subBuilder.buildPartial(); 474 } 475 476 @Override parseMessage( CodedInputStream input, ExtensionRegistryLite extensionRegistry, Descriptors.FieldDescriptor field, Message defaultInstance)477 public Object parseMessage( 478 CodedInputStream input, 479 ExtensionRegistryLite extensionRegistry, 480 Descriptors.FieldDescriptor field, 481 Message defaultInstance) 482 throws IOException { 483 Message.Builder subBuilder; 484 // When default instance is not null. The field is an extension field. 485 if (defaultInstance != null) { 486 subBuilder = defaultInstance.newBuilderForType(); 487 } else { 488 subBuilder = builder.newBuilderForField(field); 489 } 490 if (!field.isRepeated()) { 491 Message originalMessage = (Message) getField(field); 492 if (originalMessage != null) { 493 subBuilder.mergeFrom(originalMessage); 494 } 495 } 496 input.readMessage(subBuilder, extensionRegistry); 497 return subBuilder.buildPartial(); 498 } 499 500 @Override parseMessageFromBytes( ByteString bytes, ExtensionRegistryLite extensionRegistry, Descriptors.FieldDescriptor field, Message defaultInstance)501 public Object parseMessageFromBytes( 502 ByteString bytes, 503 ExtensionRegistryLite extensionRegistry, 504 Descriptors.FieldDescriptor field, 505 Message defaultInstance) 506 throws IOException { 507 Message.Builder subBuilder; 508 // When default instance is not null. The field is an extension field. 509 if (defaultInstance != null) { 510 subBuilder = defaultInstance.newBuilderForType(); 511 } else { 512 subBuilder = builder.newBuilderForField(field); 513 } 514 if (!field.isRepeated()) { 515 Message originalMessage = (Message) getField(field); 516 if (originalMessage != null) { 517 subBuilder.mergeFrom(originalMessage); 518 } 519 } 520 subBuilder.mergeFrom(bytes, extensionRegistry); 521 return subBuilder.buildPartial(); 522 } 523 524 @Override newMergeTargetForField( Descriptors.FieldDescriptor field, Message defaultInstance)525 public MergeTarget newMergeTargetForField( 526 Descriptors.FieldDescriptor field, Message defaultInstance) { 527 if (defaultInstance != null) { 528 return new BuilderAdapter( 529 defaultInstance.newBuilderForType()); 530 } else { 531 return new BuilderAdapter(builder.newBuilderForField(field)); 532 } 533 } 534 535 @Override getUtf8Validation(Descriptors.FieldDescriptor descriptor)536 public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor) { 537 if (descriptor.needsUtf8Check()) { 538 return WireFormat.Utf8Validation.STRICT; 539 } 540 // TODO(liujisi): support lazy strings for repeated fields. 541 if (!descriptor.isRepeated() 542 && builder instanceof GeneratedMessage.Builder) { 543 return WireFormat.Utf8Validation.LAZY; 544 } 545 return WireFormat.Utf8Validation.LOOSE; 546 } 547 548 @Override finish()549 public Object finish() { 550 return builder.buildPartial(); 551 } 552 553 } 554 555 556 static class ExtensionAdapter implements MergeTarget { 557 558 private final FieldSet<Descriptors.FieldDescriptor> extensions; 559 ExtensionAdapter(FieldSet<Descriptors.FieldDescriptor> extensions)560 ExtensionAdapter(FieldSet<Descriptors.FieldDescriptor> extensions) { 561 this.extensions = extensions; 562 } 563 564 @Override getDescriptorForType()565 public Descriptors.Descriptor getDescriptorForType() { 566 throw new UnsupportedOperationException( 567 "getDescriptorForType() called on FieldSet object"); 568 } 569 570 @Override getField(Descriptors.FieldDescriptor field)571 public Object getField(Descriptors.FieldDescriptor field) { 572 return extensions.getField(field); 573 } 574 575 @Override hasField(Descriptors.FieldDescriptor field)576 public boolean hasField(Descriptors.FieldDescriptor field) { 577 return extensions.hasField(field); 578 } 579 580 @Override setField(Descriptors.FieldDescriptor field, Object value)581 public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) { 582 extensions.setField(field, value); 583 return this; 584 } 585 586 @Override clearField(Descriptors.FieldDescriptor field)587 public MergeTarget clearField(Descriptors.FieldDescriptor field) { 588 extensions.clearField(field); 589 return this; 590 } 591 592 @Override setRepeatedField( Descriptors.FieldDescriptor field, int index, Object value)593 public MergeTarget setRepeatedField( 594 Descriptors.FieldDescriptor field, int index, Object value) { 595 extensions.setRepeatedField(field, index, value); 596 return this; 597 } 598 599 @Override addRepeatedField(Descriptors.FieldDescriptor field, Object value)600 public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) { 601 extensions.addRepeatedField(field, value); 602 return this; 603 } 604 605 @Override hasOneof(Descriptors.OneofDescriptor oneof)606 public boolean hasOneof(Descriptors.OneofDescriptor oneof) { 607 return false; 608 } 609 610 @Override clearOneof(Descriptors.OneofDescriptor oneof)611 public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) { 612 // Nothing to clear. 613 return this; 614 } 615 616 @Override getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof)617 public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) { 618 return null; 619 } 620 621 @Override getContainerType()622 public ContainerType getContainerType() { 623 return ContainerType.EXTENSION_SET; 624 } 625 626 @Override findExtensionByName( ExtensionRegistry registry, String name)627 public ExtensionRegistry.ExtensionInfo findExtensionByName( 628 ExtensionRegistry registry, String name) { 629 return registry.findImmutableExtensionByName(name); 630 } 631 632 @Override findExtensionByNumber( ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber)633 public ExtensionRegistry.ExtensionInfo findExtensionByNumber( 634 ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) { 635 return registry.findImmutableExtensionByNumber(containingType, 636 fieldNumber); 637 } 638 639 @Override parseGroup( CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, Message defaultInstance)640 public Object parseGroup( 641 CodedInputStream input, 642 ExtensionRegistryLite registry, 643 Descriptors.FieldDescriptor field, 644 Message defaultInstance) 645 throws IOException { 646 Message.Builder subBuilder = 647 defaultInstance.newBuilderForType(); 648 if (!field.isRepeated()) { 649 Message originalMessage = (Message) getField(field); 650 if (originalMessage != null) { 651 subBuilder.mergeFrom(originalMessage); 652 } 653 } 654 input.readGroup(field.getNumber(), subBuilder, registry); 655 return subBuilder.buildPartial(); 656 } 657 658 @Override parseMessage( CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, Message defaultInstance)659 public Object parseMessage( 660 CodedInputStream input, 661 ExtensionRegistryLite registry, 662 Descriptors.FieldDescriptor field, 663 Message defaultInstance) 664 throws IOException { 665 Message.Builder subBuilder = 666 defaultInstance.newBuilderForType(); 667 if (!field.isRepeated()) { 668 Message originalMessage = (Message) getField(field); 669 if (originalMessage != null) { 670 subBuilder.mergeFrom(originalMessage); 671 } 672 } 673 input.readMessage(subBuilder, registry); 674 return subBuilder.buildPartial(); 675 } 676 677 @Override parseMessageFromBytes( ByteString bytes, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, Message defaultInstance)678 public Object parseMessageFromBytes( 679 ByteString bytes, 680 ExtensionRegistryLite registry, 681 Descriptors.FieldDescriptor field, 682 Message defaultInstance) 683 throws IOException { 684 Message.Builder subBuilder = defaultInstance.newBuilderForType(); 685 if (!field.isRepeated()) { 686 Message originalMessage = (Message) getField(field); 687 if (originalMessage != null) { 688 subBuilder.mergeFrom(originalMessage); 689 } 690 } 691 subBuilder.mergeFrom(bytes, registry); 692 return subBuilder.buildPartial(); 693 } 694 695 @Override newMergeTargetForField( Descriptors.FieldDescriptor descriptor, Message defaultInstance)696 public MergeTarget newMergeTargetForField( 697 Descriptors.FieldDescriptor descriptor, Message defaultInstance) { 698 throw new UnsupportedOperationException( 699 "newMergeTargetForField() called on FieldSet object"); 700 } 701 702 @Override getUtf8Validation(Descriptors.FieldDescriptor descriptor)703 public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor descriptor) { 704 if (descriptor.needsUtf8Check()) { 705 return WireFormat.Utf8Validation.STRICT; 706 } 707 // TODO(liujisi): support lazy strings for ExtesnsionSet. 708 return WireFormat.Utf8Validation.LOOSE; 709 } 710 711 @Override finish()712 public Object finish() { 713 throw new UnsupportedOperationException( 714 "finish() called on FieldSet object"); 715 } 716 717 } 718 719 /** 720 * Parses a single field into MergeTarget. The target can be Message.Builder, 721 * FieldSet or MutableMessage. 722 * 723 * Package-private because it is used by GeneratedMessage.ExtendableMessage. 724 * 725 * @param tag The tag, which should have already been read. 726 * @return {@code true} unless the tag is an end-group tag. 727 */ mergeFieldFrom( CodedInputStream input, UnknownFieldSet.Builder unknownFields, ExtensionRegistryLite extensionRegistry, Descriptors.Descriptor type, MergeTarget target, int tag)728 static boolean mergeFieldFrom( 729 CodedInputStream input, 730 UnknownFieldSet.Builder unknownFields, 731 ExtensionRegistryLite extensionRegistry, 732 Descriptors.Descriptor type, 733 MergeTarget target, 734 int tag) throws IOException { 735 if (type.getOptions().getMessageSetWireFormat() && 736 tag == WireFormat.MESSAGE_SET_ITEM_TAG) { 737 mergeMessageSetExtensionFromCodedStream( 738 input, unknownFields, extensionRegistry, type, target); 739 return true; 740 } 741 742 final int wireType = WireFormat.getTagWireType(tag); 743 final int fieldNumber = WireFormat.getTagFieldNumber(tag); 744 745 final Descriptors.FieldDescriptor field; 746 Message defaultInstance = null; 747 748 if (type.isExtensionNumber(fieldNumber)) { 749 // extensionRegistry may be either ExtensionRegistry or 750 // ExtensionRegistryLite. Since the type we are parsing is a full 751 // message, only a full ExtensionRegistry could possibly contain 752 // extensions of it. Otherwise we will treat the registry as if it 753 // were empty. 754 if (extensionRegistry instanceof ExtensionRegistry) { 755 final ExtensionRegistry.ExtensionInfo extension = 756 target.findExtensionByNumber((ExtensionRegistry) extensionRegistry, 757 type, fieldNumber); 758 if (extension == null) { 759 field = null; 760 } else { 761 field = extension.descriptor; 762 defaultInstance = extension.defaultInstance; 763 if (defaultInstance == null && 764 field.getJavaType() 765 == Descriptors.FieldDescriptor.JavaType.MESSAGE) { 766 throw new IllegalStateException( 767 "Message-typed extension lacked default instance: " + 768 field.getFullName()); 769 } 770 } 771 } else { 772 field = null; 773 } 774 } else if (target.getContainerType() == MergeTarget.ContainerType.MESSAGE) { 775 field = type.findFieldByNumber(fieldNumber); 776 } else { 777 field = null; 778 } 779 780 boolean unknown = false; 781 boolean packed = false; 782 if (field == null) { 783 unknown = true; // Unknown field. 784 } else if (wireType == FieldSet.getWireFormatForFieldType( 785 field.getLiteType(), 786 false /* isPacked */)) { 787 packed = false; 788 } else if (field.isPackable() && 789 wireType == FieldSet.getWireFormatForFieldType( 790 field.getLiteType(), 791 true /* isPacked */)) { 792 packed = true; 793 } else { 794 unknown = true; // Unknown wire type. 795 } 796 797 if (unknown) { // Unknown field or wrong wire type. Skip. 798 return unknownFields.mergeFieldFrom(tag, input); 799 } 800 801 if (packed) { 802 final int length = input.readRawVarint32(); 803 final int limit = input.pushLimit(length); 804 if (field.getLiteType() == WireFormat.FieldType.ENUM) { 805 while (input.getBytesUntilLimit() > 0) { 806 final int rawValue = input.readEnum(); 807 if (field.getFile().supportsUnknownEnumValue()) { 808 target.addRepeatedField(field, 809 field.getEnumType().findValueByNumberCreatingIfUnknown(rawValue)); 810 } else { 811 final Object value = field.getEnumType().findValueByNumber(rawValue); 812 if (value == null) { 813 // If the number isn't recognized as a valid value for this 814 // enum, drop it (don't even add it to unknownFields). 815 return true; 816 } 817 target.addRepeatedField(field, value); 818 } 819 } 820 } else { 821 while (input.getBytesUntilLimit() > 0) { 822 final Object value = WireFormat.readPrimitiveField( 823 input, field.getLiteType(), target.getUtf8Validation(field)); 824 target.addRepeatedField(field, value); 825 } 826 } 827 input.popLimit(limit); 828 } else { 829 final Object value; 830 switch (field.getType()) { 831 case GROUP: { 832 value = target 833 .parseGroup(input, extensionRegistry, field, defaultInstance); 834 break; 835 } 836 case MESSAGE: { 837 value = target 838 .parseMessage(input, extensionRegistry, field, defaultInstance); 839 break; 840 } 841 case ENUM: 842 final int rawValue = input.readEnum(); 843 if (field.getFile().supportsUnknownEnumValue()) { 844 value = field.getEnumType().findValueByNumberCreatingIfUnknown(rawValue); 845 } else { 846 value = field.getEnumType().findValueByNumber(rawValue); 847 // If the number isn't recognized as a valid value for this enum, 848 // drop it. 849 if (value == null) { 850 unknownFields.mergeVarintField(fieldNumber, rawValue); 851 return true; 852 } 853 } 854 break; 855 default: 856 value = WireFormat.readPrimitiveField( 857 input, field.getLiteType(), target.getUtf8Validation(field)); 858 break; 859 } 860 861 if (field.isRepeated()) { 862 target.addRepeatedField(field, value); 863 } else { 864 target.setField(field, value); 865 } 866 } 867 868 return true; 869 } 870 871 /** 872 * Called by {@code #mergeFieldFrom()} to parse a MessageSet extension into 873 * MergeTarget. 874 */ mergeMessageSetExtensionFromCodedStream( CodedInputStream input, UnknownFieldSet.Builder unknownFields, ExtensionRegistryLite extensionRegistry, Descriptors.Descriptor type, MergeTarget target)875 private static void mergeMessageSetExtensionFromCodedStream( 876 CodedInputStream input, 877 UnknownFieldSet.Builder unknownFields, 878 ExtensionRegistryLite extensionRegistry, 879 Descriptors.Descriptor type, 880 MergeTarget target) throws IOException { 881 882 // The wire format for MessageSet is: 883 // message MessageSet { 884 // repeated group Item = 1 { 885 // required int32 typeId = 2; 886 // required bytes message = 3; 887 // } 888 // } 889 // "typeId" is the extension's field number. The extension can only be 890 // a message type, where "message" contains the encoded bytes of that 891 // message. 892 // 893 // In practice, we will probably never see a MessageSet item in which 894 // the message appears before the type ID, or where either field does not 895 // appear exactly once. However, in theory such cases are valid, so we 896 // should be prepared to accept them. 897 898 int typeId = 0; 899 ByteString rawBytes = null; // If we encounter "message" before "typeId" 900 ExtensionRegistry.ExtensionInfo extension = null; 901 902 // Read bytes from input, if we get it's type first then parse it eagerly, 903 // otherwise we store the raw bytes in a local variable. 904 while (true) { 905 final int tag = input.readTag(); 906 if (tag == 0) { 907 break; 908 } 909 910 if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) { 911 typeId = input.readUInt32(); 912 if (typeId != 0) { 913 // extensionRegistry may be either ExtensionRegistry or 914 // ExtensionRegistryLite. Since the type we are parsing is a full 915 // message, only a full ExtensionRegistry could possibly contain 916 // extensions of it. Otherwise we will treat the registry as if it 917 // were empty. 918 if (extensionRegistry instanceof ExtensionRegistry) { 919 extension = target.findExtensionByNumber( 920 (ExtensionRegistry) extensionRegistry, type, typeId); 921 } 922 } 923 924 } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) { 925 if (typeId != 0) { 926 if (extension != null && 927 ExtensionRegistryLite.isEagerlyParseMessageSets()) { 928 // We already know the type, so we can parse directly from the 929 // input with no copying. Hooray! 930 eagerlyMergeMessageSetExtension( 931 input, extension, extensionRegistry, target); 932 rawBytes = null; 933 continue; 934 } 935 } 936 // We haven't seen a type ID yet or we want parse message lazily. 937 rawBytes = input.readBytes(); 938 939 } else { // Unknown tag. Skip it. 940 if (!input.skipField(tag)) { 941 break; // End of group 942 } 943 } 944 } 945 input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG); 946 947 // Process the raw bytes. 948 if (rawBytes != null && typeId != 0) { // Zero is not a valid type ID. 949 if (extension != null) { // We known the type 950 mergeMessageSetExtensionFromBytes( 951 rawBytes, extension, extensionRegistry, target); 952 } else { // We don't know how to parse this. Ignore it. 953 if (rawBytes != null) { 954 unknownFields.mergeField(typeId, UnknownFieldSet.Field.newBuilder() 955 .addLengthDelimited(rawBytes).build()); 956 } 957 } 958 } 959 } 960 mergeMessageSetExtensionFromBytes( ByteString rawBytes, ExtensionRegistry.ExtensionInfo extension, ExtensionRegistryLite extensionRegistry, MergeTarget target)961 private static void mergeMessageSetExtensionFromBytes( 962 ByteString rawBytes, 963 ExtensionRegistry.ExtensionInfo extension, 964 ExtensionRegistryLite extensionRegistry, 965 MergeTarget target) throws IOException { 966 967 Descriptors.FieldDescriptor field = extension.descriptor; 968 boolean hasOriginalValue = target.hasField(field); 969 970 if (hasOriginalValue || ExtensionRegistryLite.isEagerlyParseMessageSets()) { 971 // If the field already exists, we just parse the field. 972 Object value = target.parseMessageFromBytes( 973 rawBytes, extensionRegistry,field, extension.defaultInstance); 974 target.setField(field, value); 975 } else { 976 // Use LazyField to load MessageSet lazily. 977 LazyField lazyField = new LazyField( 978 extension.defaultInstance, extensionRegistry, rawBytes); 979 target.setField(field, lazyField); 980 } 981 } 982 eagerlyMergeMessageSetExtension( CodedInputStream input, ExtensionRegistry.ExtensionInfo extension, ExtensionRegistryLite extensionRegistry, MergeTarget target)983 private static void eagerlyMergeMessageSetExtension( 984 CodedInputStream input, 985 ExtensionRegistry.ExtensionInfo extension, 986 ExtensionRegistryLite extensionRegistry, 987 MergeTarget target) throws IOException { 988 Descriptors.FieldDescriptor field = extension.descriptor; 989 Object value = target.parseMessage(input, extensionRegistry, field, 990 extension.defaultInstance); 991 target.setField(field, value); 992 } 993 } 994