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