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