31 package com.google.protobuf;
34 import java.io.IOException;
35 import java.util.ArrayList;
36 import java.util.List;
38 import java.util.TreeMap;
45 class MessageReflection {
47 static void writeMessageTo(
51 boolean alwaysWriteRequiredFields)
53 final boolean isMessageSet =
54 message.getDescriptorForType().getOptions().getMessageSetWireFormat();
55 if (alwaysWriteRequiredFields) {
63 for (
final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
fields.entrySet()) {
64 final Descriptors.FieldDescriptor
field = entry.getKey();
65 final Object
value = entry.getValue();
67 &&
field.isExtension()
68 &&
field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE
69 && !
field.isRepeated()) {
78 unknownFields.writeAsMessageSetTo(
output);
80 unknownFields.writeTo(
output);
86 final boolean isMessageSet =
87 message.getDescriptorForType().getOptions().getMessageSetWireFormat();
89 for (
final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
fields.entrySet()) {
90 final Descriptors.FieldDescriptor
field = entry.getKey();
91 final Object
value = entry.getValue();
93 &&
field.isExtension()
94 &&
field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE
95 && !
field.isRepeated()) {
97 CodedOutputStream.computeMessageSetExtensionSize(
field.getNumber(), (Message)
value);
105 size += unknownFields.getSerializedSizeAsMessageSet();
107 size += unknownFields.getSerializedSize();
112 static String delimitWithCommas(List<String> parts) {
113 StringBuilder result =
new StringBuilder();
114 for (String part : parts) {
115 if (result.length() > 0) {
120 return result.toString();
123 @SuppressWarnings(
"unchecked")
124 static
boolean isInitialized(MessageOrBuilder
message) {
126 for (
final Descriptors.FieldDescriptor
field :
message.getDescriptorForType().getFields()) {
127 if (
field.isRequired()) {
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()) {
146 if (!((Message) entry.getValue()).isInitialized()) {
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(
')');
162 result.append(
field.getName());
165 result.append(
'[').append(
index).append(
']');
168 return result.toString();
171 private static void findMissingFields(
173 for (
final Descriptors.FieldDescriptor
field :
message.getDescriptorForType().getFields()) {
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();
184 if (
field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
185 if (
field.isRepeated()) {
187 for (
final Object element : (List)
value) {
205 static List<String> findMissingFields(
final MessageOrBuilder
message) {
206 final List<String>
results =
new ArrayList<String>();
211 static interface MergeTarget {
319 Object parseMessageFromBytes(
334 MergeTarget newMergeTargetForField(
342 MergeTarget newEmptyTargetForField(
349 static class BuilderAdapter
implements MergeTarget {
355 return builder.getDescriptorForType();
359 this.builder = builder;
363 public Object getField(Descriptors.FieldDescriptor
field) {
364 return builder.getField(
field);
368 public boolean hasField(Descriptors.FieldDescriptor
field) {
369 return builder.hasField(
field);
373 public MergeTarget setField(Descriptors.FieldDescriptor
field, Object
value) {
379 public MergeTarget clearField(Descriptors.FieldDescriptor
field) {
380 builder.clearField(
field);
385 public MergeTarget setRepeatedField(
392 public MergeTarget addRepeatedField(Descriptors.FieldDescriptor
field, Object
value) {
398 public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
399 return builder.hasOneof(oneof);
403 public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
404 builder.clearOneof(oneof);
409 public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
410 return builder.getOneofFieldDescriptor(oneof);
414 public ContainerType getContainerType() {
415 return ContainerType.MESSAGE;
419 public ExtensionRegistry.ExtensionInfo findExtensionByName(
420 ExtensionRegistry registry, String
name) {
421 return registry.findImmutableExtensionByName(
name);
425 public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
426 ExtensionRegistry registry, Descriptors.Descriptor containingType,
int fieldNumber) {
427 return registry.findImmutableExtensionByNumber(containingType, fieldNumber);
431 public Object parseGroup(
432 CodedInputStream
input,
433 ExtensionRegistryLite extensionRegistry,
434 Descriptors.FieldDescriptor
field,
435 Message defaultInstance)
437 Message.Builder subBuilder;
439 if (defaultInstance !=
null) {
440 subBuilder = defaultInstance.newBuilderForType();
442 subBuilder = builder.newBuilderForField(
field);
444 if (!
field.isRepeated()) {
445 Message originalMessage = (Message) getField(
field);
446 if (originalMessage !=
null) {
447 subBuilder.mergeFrom(originalMessage);
450 input.readGroup(
field.getNumber(), subBuilder, extensionRegistry);
451 return subBuilder.buildPartial();
455 public Object parseMessage(
456 CodedInputStream
input,
457 ExtensionRegistryLite extensionRegistry,
458 Descriptors.FieldDescriptor
field,
459 Message defaultInstance)
461 Message.Builder subBuilder;
463 if (defaultInstance !=
null) {
464 subBuilder = defaultInstance.newBuilderForType();
466 subBuilder = builder.newBuilderForField(
field);
468 if (!
field.isRepeated()) {
469 Message originalMessage = (Message) getField(
field);
470 if (originalMessage !=
null) {
471 subBuilder.mergeFrom(originalMessage);
474 input.readMessage(subBuilder, extensionRegistry);
475 return subBuilder.buildPartial();
479 public Object parseMessageFromBytes(
481 ExtensionRegistryLite extensionRegistry,
482 Descriptors.FieldDescriptor
field,
483 Message defaultInstance)
485 Message.Builder subBuilder;
487 if (defaultInstance !=
null) {
488 subBuilder = defaultInstance.newBuilderForType();
490 subBuilder = builder.newBuilderForField(
field);
492 if (!
field.isRepeated()) {
493 Message originalMessage = (Message) getField(
field);
494 if (originalMessage !=
null) {
495 subBuilder.mergeFrom(originalMessage);
498 subBuilder.mergeFrom(
bytes, extensionRegistry);
499 return subBuilder.buildPartial();
503 public MergeTarget newMergeTargetForField(
504 Descriptors.FieldDescriptor
field, Message defaultInstance) {
505 Message.Builder subBuilder;
506 if (defaultInstance !=
null) {
507 subBuilder = defaultInstance.newBuilderForType();
509 subBuilder = builder.newBuilderForField(
field);
511 if (!
field.isRepeated()) {
512 Message originalMessage = (Message) getField(
field);
513 if (originalMessage !=
null) {
514 subBuilder.mergeFrom(originalMessage);
517 return new BuilderAdapter(subBuilder);
521 public MergeTarget newEmptyTargetForField(
522 Descriptors.FieldDescriptor
field, Message defaultInstance) {
523 Message.Builder subBuilder;
524 if (defaultInstance !=
null) {
525 subBuilder = defaultInstance.newBuilderForType();
527 subBuilder = builder.newBuilderForField(
field);
529 return new BuilderAdapter(subBuilder);
533 public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor
descriptor) {
535 return WireFormat.Utf8Validation.STRICT;
538 if (!
descriptor.isRepeated() && builder instanceof GeneratedMessage.Builder) {
539 return WireFormat.Utf8Validation.LAZY;
541 return WireFormat.Utf8Validation.LOOSE;
545 public Object finish() {
546 return builder.buildPartial();
551 static class ExtensionAdapter
implements MergeTarget {
553 private final FieldSet<Descriptors.FieldDescriptor> extensions;
555 ExtensionAdapter(FieldSet<Descriptors.FieldDescriptor> extensions) {
556 this.extensions = extensions;
560 public Descriptors.Descriptor getDescriptorForType() {
561 throw new UnsupportedOperationException(
"getDescriptorForType() called on FieldSet object");
565 public Object getField(Descriptors.FieldDescriptor
field) {
566 return extensions.getField(
field);
570 public boolean hasField(Descriptors.FieldDescriptor
field) {
571 return extensions.hasField(
field);
575 public MergeTarget setField(Descriptors.FieldDescriptor
field, Object
value) {
581 public MergeTarget clearField(Descriptors.FieldDescriptor
field) {
582 extensions.clearField(
field);
587 public MergeTarget setRepeatedField(
594 public MergeTarget addRepeatedField(Descriptors.FieldDescriptor
field, Object
value) {
600 public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
605 public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
611 public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
616 public ContainerType getContainerType() {
617 return ContainerType.EXTENSION_SET;
621 public ExtensionRegistry.ExtensionInfo findExtensionByName(
622 ExtensionRegistry registry, String
name) {
623 return registry.findImmutableExtensionByName(
name);
627 public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
628 ExtensionRegistry registry, Descriptors.Descriptor containingType,
int fieldNumber) {
629 return registry.findImmutableExtensionByNumber(containingType, fieldNumber);
633 public Object parseGroup(
634 CodedInputStream
input,
635 ExtensionRegistryLite registry,
636 Descriptors.FieldDescriptor
field,
637 Message defaultInstance)
639 Message.Builder subBuilder = defaultInstance.newBuilderForType();
640 if (!
field.isRepeated()) {
641 Message originalMessage = (Message) getField(
field);
642 if (originalMessage !=
null) {
643 subBuilder.mergeFrom(originalMessage);
646 input.readGroup(
field.getNumber(), subBuilder, registry);
647 return subBuilder.buildPartial();
651 public Object parseMessage(
652 CodedInputStream
input,
653 ExtensionRegistryLite registry,
654 Descriptors.FieldDescriptor
field,
655 Message defaultInstance)
657 Message.Builder subBuilder = defaultInstance.newBuilderForType();
658 if (!
field.isRepeated()) {
659 Message originalMessage = (Message) getField(
field);
660 if (originalMessage !=
null) {
661 subBuilder.mergeFrom(originalMessage);
664 input.readMessage(subBuilder, registry);
665 return subBuilder.buildPartial();
669 public Object parseMessageFromBytes(
671 ExtensionRegistryLite registry,
672 Descriptors.FieldDescriptor
field,
673 Message defaultInstance)
675 Message.Builder subBuilder = defaultInstance.newBuilderForType();
676 if (!
field.isRepeated()) {
677 Message originalMessage = (Message) getField(
field);
678 if (originalMessage !=
null) {
679 subBuilder.mergeFrom(originalMessage);
682 subBuilder.mergeFrom(
bytes, registry);
683 return subBuilder.buildPartial();
687 public MergeTarget newMergeTargetForField(
688 Descriptors.FieldDescriptor
descriptor, Message defaultInstance) {
689 throw new UnsupportedOperationException(
"newMergeTargetForField() called on FieldSet object");
693 public MergeTarget newEmptyTargetForField(
694 Descriptors.FieldDescriptor
descriptor, Message defaultInstance) {
695 throw new UnsupportedOperationException(
"newEmptyTargetForField() called on FieldSet object");
699 public WireFormat.Utf8Validation getUtf8Validation(Descriptors.FieldDescriptor
descriptor) {
701 return WireFormat.Utf8Validation.STRICT;
704 return WireFormat.Utf8Validation.LOOSE;
708 public Object finish() {
709 throw new UnsupportedOperationException(
"finish() called on FieldSet object");
724 static boolean mergeFieldFrom(
725 CodedInputStream
input,
727 ExtensionRegistryLite extensionRegistry,
728 Descriptors.Descriptor
type,
732 if (
type.getOptions().getMessageSetWireFormat() && tag == WireFormat.MESSAGE_SET_ITEM_TAG) {
733 mergeMessageSetExtensionFromCodedStream(
738 final int wireType = WireFormat.getTagWireType(tag);
739 final int fieldNumber = WireFormat.getTagFieldNumber(tag);
741 final Descriptors.FieldDescriptor
field;
742 Message defaultInstance =
null;
744 if (
type.isExtensionNumber(fieldNumber)) {
750 if (extensionRegistry instanceof ExtensionRegistry) {
751 final ExtensionRegistry.ExtensionInfo
extension =
752 target.findExtensionByNumber((ExtensionRegistry) extensionRegistry,
type, fieldNumber);
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());
767 }
else if (
target.getContainerType() == MergeTarget.ContainerType.MESSAGE) {
768 field =
type.findFieldByNumber(fieldNumber);
773 boolean unknown =
false;
774 boolean packed =
false;
778 == FieldSet.getWireFormatForFieldType(
field.getLiteType(),
false)) {
780 }
else if (
field.isPackable()
782 == FieldSet.getWireFormatForFieldType(
field.getLiteType(),
true)) {
789 if (unknownFields !=
null) {
790 return unknownFields.mergeFieldFrom(tag,
input);
792 return input.skipField(tag);
799 if (
field.getLiteType() == WireFormat.FieldType.ENUM) {
800 while (
input.getBytesUntilLimit() > 0) {
801 final int rawValue =
input.readEnum();
802 if (
field.getFile().supportsUnknownEnumValue()) {
804 field,
field.getEnumType().findValueByNumberCreatingIfUnknown(rawValue));
806 final Object
value =
field.getEnumType().findValueByNumber(rawValue);
810 if (unknownFields !=
null) {
811 unknownFields.mergeVarintField(fieldNumber, rawValue);
819 while (
input.getBytesUntilLimit() > 0) {
821 WireFormat.readPrimitiveField(
826 input.popLimit(limit);
829 switch (
field.getType()) {
841 final int rawValue =
input.readEnum();
842 if (
field.getFile().supportsUnknownEnumValue()) {
843 value =
field.getEnumType().findValueByNumberCreatingIfUnknown(rawValue);
845 value =
field.getEnumType().findValueByNumber(rawValue);
849 if (unknownFields !=
null) {
850 unknownFields.mergeVarintField(fieldNumber, rawValue);
858 WireFormat.readPrimitiveField(
863 if (
field.isRepeated()) {
874 private static void mergeMessageSetExtensionFromCodedStream(
875 CodedInputStream
input,
877 ExtensionRegistryLite extensionRegistry,
878 Descriptors.Descriptor
type,
899 ByteString rawBytes =
null;
900 ExtensionRegistry.ExtensionInfo
extension =
null;
905 final int tag =
input.readTag();
910 if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) {
911 typeId =
input.readUInt32();
918 if (extensionRegistry instanceof ExtensionRegistry) {
920 target.findExtensionByNumber((ExtensionRegistry) extensionRegistry,
type, typeId);
924 }
else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) {
926 if (
extension !=
null && ExtensionRegistryLite.isEagerlyParseMessageSets()) {
935 rawBytes =
input.readBytes();
938 if (!
input.skipField(tag)) {
943 input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG);
946 if (rawBytes !=
null && typeId != 0) {
948 mergeMessageSetExtensionFromBytes(rawBytes,
extension, extensionRegistry,
target);
950 if (rawBytes !=
null && unknownFields !=
null) {
951 unknownFields.mergeField(
952 typeId,
UnknownFieldSet.Field.newBuilder().addLengthDelimited(rawBytes).build());
958 private static void mergeMessageSetExtensionFromBytes(
960 ExtensionRegistry.ExtensionInfo
extension,
961 ExtensionRegistryLite extensionRegistry,
968 if (hasOriginalValue || ExtensionRegistryLite.isEagerlyParseMessageSets()) {
971 target.parseMessageFromBytes(
976 LazyField lazyField =
new LazyField(
extension.defaultInstance, extensionRegistry, rawBytes);
981 private static void eagerlyMergeMessageSetExtension(
982 CodedInputStream
input,
983 ExtensionRegistry.ExtensionInfo
extension,
984 ExtensionRegistryLite extensionRegistry,