MessageReflection.java
Go to the documentation of this file.
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 
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 
45 class MessageReflection {
46 
47  static void writeMessageTo(
48  Message message,
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 
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 
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")
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 
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 
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 
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 {
214  EXTENSION_SET
215  }
216 
218  public Descriptors.Descriptor getDescriptorForType();
219 
220  public ContainerType getContainerType();
221 
222  public ExtensionRegistry.ExtensionInfo findExtensionByName(
223  ExtensionRegistry registry, String name);
224 
225  public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
226  ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber);
227 
234  public Object getField(Descriptors.FieldDescriptor field);
235 
243  boolean hasField(Descriptors.FieldDescriptor field);
244 
249  MergeTarget setField(Descriptors.FieldDescriptor field, Object value);
250 
255  MergeTarget clearField(Descriptors.FieldDescriptor field);
256 
265  MergeTarget setRepeatedField(Descriptors.FieldDescriptor field, int index, Object value);
266 
273  MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value);
274 
281  boolean hasOneof(Descriptors.OneofDescriptor oneof);
282 
287  MergeTarget clearOneof(Descriptors.OneofDescriptor oneof);
288 
290  Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof);
291 
296  Object parseGroup(
298  ExtensionRegistryLite registry,
300  Message defaultInstance)
301  throws IOException;
302 
307  Object parseMessage(
309  ExtensionRegistryLite registry,
311  Message defaultInstance)
312  throws IOException;
313 
319  Object parseMessageFromBytes(
321  ExtensionRegistryLite registry,
323  Message defaultInstance)
324  throws IOException;
325 
328 
334  MergeTarget newMergeTargetForField(
335  Descriptors.FieldDescriptor descriptor, Message defaultInstance);
336 
342  MergeTarget newEmptyTargetForField(
343  Descriptors.FieldDescriptor descriptor, Message defaultInstance);
344 
346  Object finish();
347  }
348 
349  static class BuilderAdapter implements MergeTarget {
350 
351  private final Message.Builder builder;
352 
353  @Override
354  public Descriptors.Descriptor getDescriptorForType() {
355  return builder.getDescriptorForType();
356  }
357 
358  public BuilderAdapter(Message.Builder builder) {
359  this.builder = builder;
360  }
361 
362  @Override
363  public Object getField(Descriptors.FieldDescriptor field) {
364  return builder.getField(field);
365  }
366 
367  @Override
368  public boolean hasField(Descriptors.FieldDescriptor field) {
369  return builder.hasField(field);
370  }
371 
372  @Override
373  public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) {
374  builder.setField(field, value);
375  return this;
376  }
377 
378  @Override
379  public MergeTarget clearField(Descriptors.FieldDescriptor field) {
380  builder.clearField(field);
381  return this;
382  }
383 
384  @Override
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
392  public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
393  builder.addRepeatedField(field, value);
394  return this;
395  }
396 
397  @Override
398  public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
399  return builder.hasOneof(oneof);
400  }
401 
402  @Override
403  public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
404  builder.clearOneof(oneof);
405  return this;
406  }
407 
408  @Override
409  public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
410  return builder.getOneofFieldDescriptor(oneof);
411  }
412 
413  @Override
414  public ContainerType getContainerType() {
415  return ContainerType.MESSAGE;
416  }
417 
418  @Override
419  public ExtensionRegistry.ExtensionInfo findExtensionByName(
420  ExtensionRegistry registry, String name) {
421  return registry.findImmutableExtensionByName(name);
422  }
423 
424  @Override
425  public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
426  ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
427  return registry.findImmutableExtensionByNumber(containingType, fieldNumber);
428  }
429 
430  @Override
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
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
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
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
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
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
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 
555  ExtensionAdapter(FieldSet<Descriptors.FieldDescriptor> extensions) {
556  this.extensions = extensions;
557  }
558 
559  @Override
560  public Descriptors.Descriptor getDescriptorForType() {
561  throw new UnsupportedOperationException("getDescriptorForType() called on FieldSet object");
562  }
563 
564  @Override
565  public Object getField(Descriptors.FieldDescriptor field) {
566  return extensions.getField(field);
567  }
568 
569  @Override
570  public boolean hasField(Descriptors.FieldDescriptor field) {
571  return extensions.hasField(field);
572  }
573 
574  @Override
575  public MergeTarget setField(Descriptors.FieldDescriptor field, Object value) {
576  extensions.setField(field, value);
577  return this;
578  }
579 
580  @Override
581  public MergeTarget clearField(Descriptors.FieldDescriptor field) {
582  extensions.clearField(field);
583  return this;
584  }
585 
586  @Override
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
594  public MergeTarget addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
595  extensions.addRepeatedField(field, value);
596  return this;
597  }
598 
599  @Override
600  public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
601  return false;
602  }
603 
604  @Override
605  public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
606  // Nothing to clear.
607  return this;
608  }
609 
610  @Override
611  public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
612  return null;
613  }
614 
615  @Override
616  public ContainerType getContainerType() {
617  return ContainerType.EXTENSION_SET;
618  }
619 
620  @Override
621  public ExtensionRegistry.ExtensionInfo findExtensionByName(
622  ExtensionRegistry registry, String name) {
623  return registry.findImmutableExtensionByName(name);
624  }
625 
626  @Override
627  public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
628  ExtensionRegistry registry, Descriptors.Descriptor containingType, int fieldNumber) {
629  return registry.findImmutableExtensionByNumber(containingType, fieldNumber);
630  }
631 
632  @Override
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
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
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
687  public MergeTarget newMergeTargetForField(
688  Descriptors.FieldDescriptor descriptor, Message defaultInstance) {
689  throw new UnsupportedOperationException("newMergeTargetForField() called on FieldSet object");
690  }
691 
692  @Override
693  public MergeTarget newEmptyTargetForField(
694  Descriptors.FieldDescriptor descriptor, Message defaultInstance) {
695  throw new UnsupportedOperationException("newEmptyTargetForField() called on FieldSet object");
696  }
697 
698  @Override
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
708  public Object finish() {
709  throw new UnsupportedOperationException("finish() called on FieldSet object");
710  }
711  }
712 
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 
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 
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 
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 }
com.google.protobuf.Descriptors
Definition: Descriptors.java:80
name
GLuint const GLchar * name
Definition: glcorearb.h:3055
Map
Definition: ruby/ext/google/protobuf_c/protobuf.h:442
google::protobuf::extension
const Descriptor::ReservedRange const EnumValueDescriptor const MethodDescriptor extension
Definition: src/google/protobuf/descriptor.h:2001
length
GLenum GLuint GLenum GLsizei length
Definition: glcorearb.h:2695
input
std::string input
Definition: tokenizer_unittest.cc:197
com.google.protobuf.ExtensionRegistry.ExtensionInfo
Definition: ExtensionRegistry.java:110
com.google.protobuf
Definition: ProtoCaliperBenchmark.java:2
com.google.protobuf.MessageReflection.MergeTarget.ContainerType.MESSAGE
MESSAGE
Definition: MessageReflection.java:213
target
GLenum target
Definition: glcorearb.h:3739
descriptor
Descriptor * descriptor
Definition: php/ext/google/protobuf/protobuf.h:936
com.google.protobuf.WireFormat
Definition: WireFormat.java:45
google::protobuf::python::cmessage::UnknownFieldSet
static PyObject * UnknownFieldSet(CMessage *self)
Definition: python/google/protobuf/pyext/message.cc:2501
bytes
uint8 bytes[10]
Definition: coded_stream_unittest.cc:153
FieldDescriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:129
com.google.protobuf.CodedInputStream
Definition: CodedInputStream.java:61
com.google.protobuf.MessageReflection.MergeTarget.ContainerType
Definition: MessageReflection.java:212
com.google.protobuf.Descriptors.OneofDescriptor
Definition: Descriptors.java:2597
com.google.protobuf.Message.Builder
Definition: Message.java:104
benchmarks.python.py_benchmark.results
list results
Definition: py_benchmark.py:145
prefix
static const char prefix[]
Definition: test_pair_ipc.cpp:26
size
#define size
Definition: glcorearb.h:2944
com.google.protobuf.ExtensionRegistryLite
Definition: ExtensionRegistryLite.java:70
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
i
int i
Definition: gmock-matchers_test.cc:764
java
com.google.protobuf.Descriptors.Descriptor
Definition: Descriptors.java:629
fields
static const upb_fielddef fields[107]
Definition: ruby/ext/google/protobuf_c/upb.c:7671
type
GLenum type
Definition: glcorearb.h:2695
size
GLsizeiptr size
Definition: glcorearb.h:2943
com.google
com.google.protobuf.WireFormat.Utf8Validation
Definition: WireFormat.java:188
com
com.google.protobuf.ExtensionRegistry
Definition: ExtensionRegistry.java:91
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
output
const upb_json_parsermethod const upb_symtab upb_sink * output
Definition: ruby/ext/google/protobuf_c/upb.h:10503
index
GLuint index
Definition: glcorearb.h:3055
message
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glcorearb.h:2695
com.google.protobuf.Message
Definition: Message.java:50
com.google.protobuf.Descriptors.FieldDescriptor
Definition: Descriptors.java:949
com.google.protobuf.ByteString
Definition: ByteString.java:67


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:56