36 """Contains a metaclass and helper functions used to create
37 protocol message classes from Descriptor objects at runtime.
39 Recall that a metaclass is the "type" of a class.
40 (A class is to a metaclass what an instance is to a class.)
42 In this case, we use the GeneratedProtocolMessageType metaclass
43 to inject all the useful functionality into the classes
44 output by the protocol compiler at compile-time.
46 The upshot of all this is that the real implementation
47 details for ALL pure-Python protocol buffers are *here in
51 __author__ =
'robinson@google.com (Will Robinson)'
53 from io
import BytesIO
73 _FieldDescriptor = descriptor_mod.FieldDescriptor
74 _AnyFullTypeName =
'google.protobuf.Any'
75 _ExtensionDict = extension_dict._ExtensionDict
79 """Metaclass for protocol message classes created at runtime from Descriptors.
81 We add implementations for all methods described in the Message class. We
82 also create properties to allow getting/setting all fields in the protocol
83 message. Finally, we create slots to prevent users from accidentally
84 "setting" nonexistent fields in the protocol message, which then wouldn't get
85 serialized / deserialized properly.
87 The protocol compiler currently uses this metaclass to create protocol
88 message classes at runtime. Clients can also manually create their own
89 classes at runtime, as in this example:
91 mydescriptor = Descriptor(.....)
92 factory = symbol_database.Default()
93 factory.pool.AddDescriptor(mydescriptor)
94 MyProtoClass = factory.GetPrototype(mydescriptor)
95 myproto_instance = MyProtoClass()
96 myproto.foo_field = 23
102 _DESCRIPTOR_KEY =
'DESCRIPTOR'
105 """Custom allocation for runtime-generated class types.
107 We override __new__ because this is apparently the only place
108 where we can meaningfully set __slots__ on the class we're creating(?).
109 (The interplay between metaclasses and slots is not very well-documented).
112 name: Name of the class (ignored, but required by the
114 bases: Base classes of the class we're constructing.
115 (Should be message.Message). We ignore this field, but
116 it's required by the metaclass protocol
117 dictionary: The class dictionary of the class we're
118 constructing. dictionary[_DESCRIPTOR_KEY] must contain
119 a Descriptor object describing this protocol message
123 Newly-allocated class.
126 RuntimeError: Generated code only work with python cpp extension.
128 descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
130 if isinstance(descriptor, str):
131 raise RuntimeError(
'The generated code only work with python cpp '
132 'extension, but it is using pure python runtime.')
144 new_class = getattr(descriptor,
'_concrete_class',
None)
148 if descriptor.full_name
in well_known_types.WKTBASES:
149 bases += (well_known_types.WKTBASES[descriptor.full_name],)
153 superclass = super(GeneratedProtocolMessageType, cls)
154 new_class = superclass.__new__(cls, name, bases, dictionary)
158 """Here we perform the majority of our work on the class.
159 We add enum getters, an __init__ method, implementations
160 of all Message methods, and properties for all fields
161 in the protocol type.
164 name: Name of the class (ignored, but required by the
166 bases: Base classes of the class we're constructing.
167 (Should be message.Message). We ignore this field, but
168 it's required by the metaclass protocol
169 dictionary: The class dictionary of the class we're
170 constructing. dictionary[_DESCRIPTOR_KEY] must contain
171 a Descriptor object describing this protocol message
174 descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
178 existing_class = getattr(descriptor,
'_concrete_class',
None)
180 assert existing_class
is cls, (
181 'Duplicate `GeneratedProtocolMessageType` created for descriptor %r'
182 % (descriptor.full_name))
186 if (descriptor.has_options
and
187 descriptor.GetOptions().message_set_wire_format):
189 decoder.MessageSetItemDecoder(descriptor),
None)
192 for field
in descriptor.fields:
195 descriptor._concrete_class = cls
204 superclass = super(GeneratedProtocolMessageType, cls)
205 superclass.__init__(name, bases, dictionary)
217 """Returns the name of the public property attribute which
218 clients can use to get and (in some cases) set the value
219 of a protocol message field.
222 proto_field_name: The protocol message field name, exactly
223 as it appears (or would appear) in a .proto file.
242 return proto_field_name
245 def _AddSlots(message_descriptor, dictionary):
246 """Adds a __slots__ entry to dictionary, containing the names of all valid
247 attributes for this message type.
250 message_descriptor: A Descriptor instance describing this message type.
251 dictionary: Class dictionary to which we'll add a '__slots__' entry.
253 dictionary[
'__slots__'] = [
'_cached_byte_size',
254 '_cached_byte_size_dirty',
257 '_unknown_field_set',
258 '_is_present_in_parent',
260 '_listener_for_children',
266 return (field.is_extension
and
267 field.containing_type.has_options
and
268 field.containing_type.GetOptions().message_set_wire_format
and
269 field.type == _FieldDescriptor.TYPE_MESSAGE
and
270 field.label == _FieldDescriptor.LABEL_OPTIONAL)
274 return (field.type == _FieldDescriptor.TYPE_MESSAGE
and
275 field.message_type.has_options
and
276 field.message_type.GetOptions().map_entry)
280 value_type = field.message_type.fields_by_name[
'value']
281 return value_type.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE
285 is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED)
286 is_packable = (is_repeated
and
287 wire_format.IsTypePackable(field_descriptor.type))
288 is_proto3 = field_descriptor.containing_type.syntax ==
'proto3'
291 elif field_descriptor.containing_type.syntax ==
'proto2':
292 is_packed = (field_descriptor.has_options
and
293 field_descriptor.GetOptions().packed)
295 has_packed_false = (field_descriptor.has_options
and
296 field_descriptor.GetOptions().
HasField(
'packed')
and
297 field_descriptor.GetOptions().packed ==
False)
298 is_packed =
not has_packed_false
302 field_encoder = encoder.MapEncoder(field_descriptor)
303 sizer = encoder.MapSizer(field_descriptor,
306 field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number)
307 sizer = encoder.MessageSetItemSizer(field_descriptor.number)
309 field_encoder = type_checkers.TYPE_TO_ENCODER[field_descriptor.type](
310 field_descriptor.number, is_repeated, is_packed)
311 sizer = type_checkers.TYPE_TO_SIZER[field_descriptor.type](
312 field_descriptor.number, is_repeated, is_packed)
314 field_descriptor._encoder = field_encoder
315 field_descriptor._sizer = sizer
319 def AddDecoder(wiretype, is_packed):
320 tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype)
321 decode_type = field_descriptor.type
322 if (decode_type == _FieldDescriptor.TYPE_ENUM
and
323 type_checkers.SupportsOpenEnums(field_descriptor)):
324 decode_type = _FieldDescriptor.TYPE_INT32
326 oneof_descriptor =
None
327 clear_if_default =
False
328 if field_descriptor.containing_oneof
is not None:
329 oneof_descriptor = field_descriptor
330 elif (is_proto3
and not is_repeated
and
331 field_descriptor.cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE):
332 clear_if_default =
True
337 field_decoder = decoder.MapDecoder(
340 elif decode_type == _FieldDescriptor.TYPE_STRING:
341 field_decoder = decoder.StringDecoder(
342 field_descriptor.number, is_repeated, is_packed,
343 field_descriptor, field_descriptor._default_constructor,
345 elif field_descriptor.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
346 field_decoder = type_checkers.TYPE_TO_DECODER[decode_type](
347 field_descriptor.number, is_repeated, is_packed,
348 field_descriptor, field_descriptor._default_constructor)
350 field_decoder = type_checkers.TYPE_TO_DECODER[decode_type](
351 field_descriptor.number, is_repeated, is_packed,
353 field_descriptor, field_descriptor._default_constructor,
358 AddDecoder(type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type],
361 if is_repeated
and wire_format.IsTypePackable(field_descriptor.type):
364 AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED,
True)
368 extensions = descriptor.extensions_by_name
369 for extension_name, extension_field
in extensions.items():
370 assert extension_name
not in dictionary
371 dictionary[extension_name] = extension_field
375 """Sets class-level attributes for all enum fields defined in this message.
377 Also exporting a class-level object that can name enum values.
380 descriptor: Descriptor object for this message type.
381 cls: Class we're constructing for this message type.
383 for enum_type
in descriptor.enum_types:
385 for enum_value
in enum_type.values:
386 setattr(cls, enum_value.name, enum_value.number)
390 if field.label != _FieldDescriptor.LABEL_REPEATED:
391 raise ValueError(
'map_entry set on non-repeated field %s' % (
393 fields_by_name = field.message_type.fields_by_name
394 key_checker = type_checkers.GetTypeChecker(fields_by_name[
'key'])
396 value_field = fields_by_name[
'value']
398 def MakeMessageMapDefault(message):
400 message._listener_for_children, value_field.message_type, key_checker,
402 return MakeMessageMapDefault
404 value_checker = type_checkers.GetTypeChecker(value_field)
405 def MakePrimitiveMapDefault(message):
407 message._listener_for_children, key_checker, value_checker,
409 return MakePrimitiveMapDefault
412 """Returns a function which returns a default value for a field.
415 field: FieldDescriptor object for this field.
417 The returned function has one argument:
418 message: Message instance containing this field, or a weakref proxy
421 That function in turn returns a default value for this field. The default
422 value may refer back to |message| via a weak reference.
428 if field.label == _FieldDescriptor.LABEL_REPEATED:
429 if field.has_default_value
and field.default_value != []:
430 raise ValueError(
'Repeated field default value not empty list: %s' % (
431 field.default_value))
432 if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
435 message_type = field.message_type
436 def MakeRepeatedMessageDefault(message):
438 message._listener_for_children, field.message_type)
439 return MakeRepeatedMessageDefault
441 type_checker = type_checkers.GetTypeChecker(field)
442 def MakeRepeatedScalarDefault(message):
444 message._listener_for_children, type_checker)
445 return MakeRepeatedScalarDefault
447 if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
449 message_type = field.message_type
450 def MakeSubMessageDefault(message):
451 assert getattr(message_type,
'_concrete_class',
None), (
452 'Uninitialized concrete class found for field %r (message type %r)'
453 % (field.full_name, message_type.full_name))
454 result = message_type._concrete_class()
457 if field.containing_oneof
is not None
458 else message._listener_for_children)
460 return MakeSubMessageDefault
462 def MakeScalarDefault(message):
465 return field.default_value
466 return MakeScalarDefault
470 """Re-raise the currently-handled TypeError with the field name added."""
471 exc = sys.exc_info()[1]
472 if len(exc.args) == 1
and type(exc)
is TypeError:
474 exc = TypeError(
'%s for field %s.%s' % (
str(exc), message_name, field_name))
477 raise exc.with_traceback(sys.exc_info()[2])
481 """Adds an __init__ method to cls."""
483 def _GetIntegerEnumValue(enum_type, value):
484 """Convert a string or integer enum value to an integer.
486 If the value is a string, it is converted to the enum value in
487 enum_type with the same name. If the value is not a string, it's
488 returned as-is. (No conversion or bounds-checking is done.)
490 if isinstance(value, str):
492 return enum_type.values_by_name[value].number
494 raise ValueError(
'Enum type %s: unknown label "%s"' % (
495 enum_type.full_name, value))
498 def init(self, **kwargs):
499 self._cached_byte_size = 0
500 self._cached_byte_size_dirty =
len(kwargs) > 0
508 self._unknown_fields = ()
511 self._unknown_field_set =
None
512 self._is_present_in_parent =
False
513 self._listener = message_listener_mod.NullMessageListener()
514 self._listener_for_children =
_Listener(self)
515 for field_name, field_value
in kwargs.items():
518 raise TypeError(
'%s() got an unexpected keyword argument "%s"' %
519 (message_descriptor.name, field_name))
520 if field_value
is None:
523 if field.label == _FieldDescriptor.LABEL_REPEATED:
524 copy = field._default_constructor(self)
525 if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
528 for key
in field_value:
531 copy.update(field_value)
533 for val
in field_value:
534 if isinstance(val, dict):
539 if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM:
540 field_value = [_GetIntegerEnumValue(field.enum_type, val)
541 for val
in field_value]
542 copy.extend(field_value)
543 self._fields[field] = copy
544 elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
545 copy = field._default_constructor(self)
546 new_val = field_value
547 if isinstance(field_value, dict):
548 new_val = field.message_type._concrete_class(**field_value)
550 copy.MergeFrom(new_val)
553 self._fields[field] = copy
555 if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM:
556 field_value = _GetIntegerEnumValue(field.enum_type, field_value)
558 setattr(self, field_name, field_value)
562 init.__module__ =
None
568 """Returns a field descriptor by field name.
571 message_descriptor: A Descriptor describing all fields in message.
572 field_name: The name of the field to retrieve.
574 The field descriptor associated with the field name.
577 return message_descriptor.fields_by_name[field_name]
579 raise ValueError(
'Protocol message %s has no "%s" field.' %
580 (message_descriptor.name, field_name))
584 """Adds properties for all fields in this protocol message type."""
585 for field
in descriptor.fields:
588 if descriptor.is_extendable:
595 """Adds a public property for a protocol message field.
596 Clients can use this property to get and (in the case
597 of non-repeated scalar fields) directly set the value
598 of a protocol message field.
601 field: A FieldDescriptor for this field.
602 cls: The class we're constructing.
606 assert _FieldDescriptor.MAX_CPPTYPE == 10
608 constant_name = field.name.upper() +
'_FIELD_NUMBER'
609 setattr(cls, constant_name, field.number)
611 if field.label == _FieldDescriptor.LABEL_REPEATED:
613 elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
620 __slots__ = (
'DESCRIPTOR',)
622 def __init__(self, descriptor, getter, setter, doc):
623 property.__init__(self, getter, setter, doc=doc)
628 """Adds a public property for a "repeated" protocol message field. Clients
629 can use this property to get the value of the field, which will be either a
630 RepeatedScalarFieldContainer or RepeatedCompositeFieldContainer (see
633 Note that when clients add values to these containers, we perform
634 type-checking in the case of repeated scalar fields, and we also set any
635 necessary "has" bits as a side-effect.
638 field: A FieldDescriptor for this field.
639 cls: The class we're constructing.
641 proto_field_name = field.name
645 field_value = self._fields.
get(field)
646 if field_value
is None:
648 field_value = field._default_constructor(self)
656 field_value = self._fields.setdefault(field, field_value)
658 getter.__module__ =
None
659 getter.__doc__ =
'Getter for %s.' % proto_field_name
663 def setter(self, new_value):
664 raise AttributeError(
'Assignment not allowed to repeated field '
665 '"%s" in protocol message object.' % proto_field_name)
667 doc =
'Magic attribute generated for "%s" proto field.' % proto_field_name
668 setattr(cls, property_name,
_FieldProperty(field, getter, setter, doc=doc))
672 """Adds a public property for a nonrepeated, scalar protocol message field.
673 Clients can use this property to get and directly set the value of the field.
674 Note that when the client sets the value of a field by using this property,
675 all necessary "has" bits are set as a side-effect, and we also perform
679 field: A FieldDescriptor for this field.
680 cls: The class we're constructing.
682 proto_field_name = field.name
684 type_checker = type_checkers.GetTypeChecker(field)
685 default_value = field.default_value
686 is_proto3 = field.containing_type.syntax ==
'proto3'
691 return self._fields.
get(field, default_value)
692 getter.__module__ =
None
693 getter.__doc__ =
'Getter for %s.' % proto_field_name
695 clear_when_set_to_default = is_proto3
and not field.containing_oneof
697 def field_setter(self, new_value):
702 new_value = type_checker.CheckValue(new_value)
703 except TypeError
as e:
705 'Cannot set %s to %.1024r: %s' % (field.full_name, new_value, e))
706 if clear_when_set_to_default
and not new_value:
707 self._fields.pop(field,
None)
709 self._fields[field] = new_value
712 if not self._cached_byte_size_dirty:
715 if field.containing_oneof:
716 def setter(self, new_value):
717 field_setter(self, new_value)
718 self._UpdateOneofState(field)
720 setter = field_setter
722 setter.__module__ =
None
723 setter.__doc__ =
'Setter for %s.' % proto_field_name
726 doc =
'Magic attribute generated for "%s" proto field.' % proto_field_name
727 setattr(cls, property_name,
_FieldProperty(field, getter, setter, doc=doc))
731 """Adds a public property for a nonrepeated, composite protocol message field.
732 A composite field is a "group" or "message" field.
734 Clients can use this property to get the value of the field, but cannot
735 assign to the property directly.
738 field: A FieldDescriptor for this field.
739 cls: The class we're constructing.
743 proto_field_name = field.name
747 field_value = self._fields.
get(field)
748 if field_value
is None:
750 field_value = field._default_constructor(self)
758 field_value = self._fields.setdefault(field, field_value)
760 getter.__module__ =
None
761 getter.__doc__ =
'Getter for %s.' % proto_field_name
765 def setter(self, new_value):
766 raise AttributeError(
'Assignment not allowed to composite field '
767 '"%s" in protocol message object.' % proto_field_name)
770 doc =
'Magic attribute generated for "%s" proto field.' % proto_field_name
771 setattr(cls, property_name,
_FieldProperty(field, getter, setter, doc=doc))
775 """Adds properties for all fields in this protocol message type."""
776 extensions = descriptor.extensions_by_name
777 for extension_name, extension_field
in extensions.items():
778 constant_name = extension_name.upper() +
'_FIELD_NUMBER'
779 setattr(cls, constant_name, extension_field.number)
783 if descriptor.file
is not None:
785 pool = descriptor.file.pool
786 cls._extensions_by_number = pool._extensions_by_number[descriptor]
787 cls._extensions_by_name = pool._extensions_by_name[descriptor]
792 extension_handle.containing_type = cls.
DESCRIPTOR
795 cls.
DESCRIPTOR.file.pool._AddExtensionDescriptor(extension_handle)
797 cls.RegisterExtension = staticmethod(RegisterExtension)
801 message.MergeFromString(s)
803 cls.FromString = staticmethod(FromString)
807 """Given a (FieldDescriptor, value) tuple from _fields, return true if the
808 value should be included in the list returned by ListFields()."""
810 if item[0].label == _FieldDescriptor.LABEL_REPEATED:
812 elif item[0].cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
813 return item[1]._is_present_in_parent
819 """Helper for _AddMessageMethods()."""
822 all_fields = [item
for item
in self._fields.
items()
if _IsPresent(item)]
823 all_fields.sort(key =
lambda item: item[0].number)
826 cls.ListFields = ListFields
828 _PROTO3_ERROR_TEMPLATE = \
829 (
'Protocol message %s has no non-repeated submessage field "%s" '
830 'nor marked as optional')
831 _PROTO2_ERROR_TEMPLATE =
'Protocol message %s has no non-repeated field "%s"'
834 """Helper for _AddMessageMethods()."""
836 is_proto3 = (message_descriptor.syntax ==
"proto3")
837 error_msg = _PROTO3_ERROR_TEMPLATE
if is_proto3
else _PROTO2_ERROR_TEMPLATE
840 for field
in message_descriptor.fields:
841 if field.label == _FieldDescriptor.LABEL_REPEATED:
844 if (is_proto3
and field.cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE
and
845 not field.containing_oneof):
847 hassable_fields[field.name] = field
850 for oneof
in message_descriptor.oneofs:
851 hassable_fields[oneof.name] = oneof
855 field = hassable_fields[field_name]
857 raise ValueError(error_msg % (message_descriptor.full_name, field_name))
859 if isinstance(field, descriptor_mod.OneofDescriptor):
861 return HasField(self, self._oneofs[field].name)
865 if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
866 value = self._fields.
get(field)
867 return value
is not None and value._is_present_in_parent
869 return field
in self._fields
871 cls.HasField = HasField
875 """Helper for _AddMessageMethods()."""
878 field = message_descriptor.fields_by_name[field_name]
881 field = message_descriptor.oneofs_by_name[field_name]
882 if field
in self._oneofs:
883 field = self._oneofs[field]
887 raise ValueError(
'Protocol message %s has no "%s" field.' %
888 (message_descriptor.name, field_name))
890 if field
in self._fields:
893 if hasattr(self._fields[field],
'InvalidateIterators'):
894 self._fields[field].InvalidateIterators()
899 del self._fields[field]
901 if self._oneofs.
get(field.containing_oneof,
None)
is field:
902 del self._oneofs[field.containing_oneof]
909 cls.ClearField = ClearField
913 """Helper for _AddMessageMethods()."""
915 extension_dict._VerifyExtensionHandle(self, extension_handle)
918 if extension_handle
in self._fields:
919 del self._fields[extension_handle]
921 cls.ClearExtension = ClearExtension
925 """Helper for _AddMessageMethods()."""
927 extension_dict._VerifyExtensionHandle(self, extension_handle)
928 if extension_handle.label == _FieldDescriptor.LABEL_REPEATED:
929 raise KeyError(
'"%s" is repeated.' % extension_handle.full_name)
931 if extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
932 value = self._fields.
get(extension_handle)
933 return value
is not None and value._is_present_in_parent
935 return extension_handle
in self._fields
936 cls.HasExtension = HasExtension
939 """Unpacks Any message and returns the unpacked message.
941 This internal method is different from public Any Unpack method which takes
942 the target message as argument. _InternalUnpackAny method does not have
943 target message type and need to find the message type in descriptor pool.
946 msg: An Any message to be unpacked.
949 The unpacked message.
956 factory = symbol_database.Default()
958 type_url = msg.type_url
965 type_name = type_url.split(
'/')[-1]
966 descriptor = factory.pool.FindMessageTypeByName(type_name)
968 if descriptor
is None:
971 message_class = factory.GetPrototype(descriptor)
972 message = message_class()
974 message.ParseFromString(msg.value)
979 """Helper for _AddMessageMethods()."""
981 if (
not isinstance(other, message_mod.Message)
or
988 if self.
DESCRIPTOR.full_name == _AnyFullTypeName:
992 return any_a == any_b
994 if not self.ListFields() == other.ListFields():
999 unknown_fields = list(self._unknown_fields)
1000 unknown_fields.sort()
1001 other_unknown_fields = list(other._unknown_fields)
1002 other_unknown_fields.sort()
1003 return unknown_fields == other_unknown_fields
1009 """Helper for _AddMessageMethods()."""
1011 return text_format.MessageToString(self)
1012 cls.__str__ = __str__
1016 """Helper for _AddMessageMethods()."""
1018 return text_format.MessageToString(self)
1019 cls.__repr__ = __repr__
1023 """Helper for _AddMessageMethods()."""
1026 return text_format.MessageToString(self, as_utf8=
True).
decode(
'utf-8')
1027 cls.__unicode__ = __unicode__
1031 """Returns the number of bytes needed to serialize a non-repeated element.
1032 The returned byte count includes space for tag information and any
1033 other additional space associated with serializing value.
1036 value: Value we're serializing.
1037 field_number: Field number of this value. (Since the field number
1038 is stored as part of a varint-encoded tag, this has an impact
1039 on the total bytes required to serialize the value).
1040 field_type: The type of the field. One of the TYPE_* constants
1041 within FieldDescriptor.
1044 fn = type_checkers.TYPE_TO_BYTE_SIZE_FN[field_type]
1045 return fn(field_number, value)
1047 raise message_mod.EncodeError(
'Unrecognized field type: %d' % field_type)
1051 """Helper for _AddMessageMethods()."""
1054 if not self._cached_byte_size_dirty:
1055 return self._cached_byte_size
1059 if descriptor.GetOptions().map_entry:
1061 size = descriptor.fields_by_name[
'key']._sizer(self.key)
1062 size += descriptor.fields_by_name[
'value']._sizer(self.value)
1064 for field_descriptor, field_value
in self.ListFields():
1065 size += field_descriptor._sizer(field_value)
1066 for tag_bytes, value_bytes
in self._unknown_fields:
1067 size +=
len(tag_bytes) +
len(value_bytes)
1069 self._cached_byte_size = size
1070 self._cached_byte_size_dirty =
False
1071 self._listener_for_children.dirty =
False
1074 cls.ByteSize = ByteSize
1078 """Helper for _AddMessageMethods()."""
1082 if not self.IsInitialized():
1083 raise message_mod.EncodeError(
1084 'Message %s is missing required fields: %s' % (
1085 self.
DESCRIPTOR.full_name,
','.join(self.FindInitializationErrors())))
1086 return self.SerializePartialToString(**kwargs)
1087 cls.SerializeToString = SerializeToString
1091 """Helper for _AddMessageMethods()."""
1095 self._InternalSerialize(out.write, **kwargs)
1096 return out.getvalue()
1097 cls.SerializePartialToString = SerializePartialToString
1099 def InternalSerialize(self, write_bytes, deterministic=None):
1100 if deterministic
is None:
1102 api_implementation.IsPythonDefaultSerializationDeterministic())
1104 deterministic = bool(deterministic)
1107 if descriptor.GetOptions().map_entry:
1109 descriptor.fields_by_name[
'key']._encoder(
1110 write_bytes, self.key, deterministic)
1111 descriptor.fields_by_name[
'value']._encoder(
1112 write_bytes, self.value, deterministic)
1114 for field_descriptor, field_value
in self.ListFields():
1115 field_descriptor._encoder(write_bytes, field_value, deterministic)
1116 for tag_bytes, value_bytes
in self._unknown_fields:
1117 write_bytes(tag_bytes)
1118 write_bytes(value_bytes)
1119 cls._InternalSerialize = InternalSerialize
1123 """Helper for _AddMessageMethods()."""
1125 serialized = memoryview(serialized)
1126 length =
len(serialized)
1128 if self._InternalParse(serialized, 0, length) != length:
1131 raise message_mod.DecodeError(
'Unexpected end-group tag.')
1132 except (IndexError, TypeError):
1134 raise message_mod.DecodeError(
'Truncated message.')
1135 except struct.error
as e:
1136 raise message_mod.DecodeError(e)
1138 cls.MergeFromString = MergeFromString
1140 local_ReadTag = decoder.ReadTag
1141 local_SkipField = decoder.SkipField
1142 decoders_by_tag = cls._decoders_by_tag
1144 def InternalParse(self, buffer, pos, end):
1145 """Create a message from serialized bytes.
1148 self: Message, instance of the proto message object.
1149 buffer: memoryview of the serialized data.
1150 pos: int, position to start in the serialized data.
1151 end: int, end position of the serialized data.
1158 assert isinstance(buffer, memoryview)
1160 field_dict = self._fields
1162 unknown_field_set = self._unknown_field_set
1164 (tag_bytes, new_pos) = local_ReadTag(buffer, pos)
1165 field_decoder, field_desc = decoders_by_tag.get(tag_bytes, (
None,
None))
1166 if field_decoder
is None:
1167 if not self._unknown_fields:
1168 self._unknown_fields = []
1169 if unknown_field_set
is None:
1173 unknown_field_set = self._unknown_field_set
1175 (tag, _) = decoder._DecodeVarint(tag_bytes, 0)
1176 field_number, wire_type = wire_format.UnpackTag(tag)
1177 if field_number == 0:
1178 raise message_mod.DecodeError(
'Field number 0 is illegal.')
1181 (data, new_pos) = decoder._DecodeUnknownField(
1182 buffer, new_pos, wire_type)
1186 unknown_field_set._add(field_number, wire_type, data)
1188 new_pos = local_SkipField(buffer, old_pos, end, tag_bytes)
1191 self._unknown_fields.append(
1192 (tag_bytes, buffer[old_pos:new_pos].tobytes()))
1195 pos = field_decoder(buffer, new_pos, end, self, field_dict)
1197 self._UpdateOneofState(field_desc)
1199 cls._InternalParse = InternalParse
1203 """Adds the IsInitialized and FindInitializationError methods to the
1204 protocol message class."""
1206 required_fields = [field
for field
in message_descriptor.fields
1207 if field.label == _FieldDescriptor.LABEL_REQUIRED]
1210 """Checks if all required fields of a message are set.
1213 errors: A list which, if provided, will be populated with the field
1214 paths of all missing required fields.
1217 True iff the specified message has all required fields set.
1222 for field
in required_fields:
1223 if (field
not in self._fields
or
1224 (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE
and
1225 not self._fields[field]._is_present_in_parent)):
1226 if errors
is not None:
1227 errors.extend(self.FindInitializationErrors())
1230 for field, value
in list(self._fields.
items()):
1231 if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
1232 if field.label == _FieldDescriptor.LABEL_REPEATED:
1233 if (field.message_type.has_options
and
1234 field.message_type.GetOptions().map_entry):
1236 for element
in value:
1237 if not element.IsInitialized():
1238 if errors
is not None:
1239 errors.extend(self.FindInitializationErrors())
1241 elif value._is_present_in_parent
and not value.IsInitialized():
1242 if errors
is not None:
1243 errors.extend(self.FindInitializationErrors())
1248 cls.IsInitialized = IsInitialized
1251 """Finds required fields which are not initialized.
1254 A list of strings. Each string is a path to an uninitialized field from
1255 the top-level message, e.g. "foo.bar[5].baz".
1260 for field
in required_fields:
1261 if not self.HasField(field.name):
1262 errors.append(field.name)
1264 for field, value
in self.ListFields():
1265 if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
1266 if field.is_extension:
1267 name =
'(%s)' % field.full_name
1274 element = value[key]
1275 prefix =
'%s[%s].' % (name, key)
1276 sub_errors = element.FindInitializationErrors()
1277 errors += [prefix + error
for error
in sub_errors]
1281 elif field.label == _FieldDescriptor.LABEL_REPEATED:
1284 prefix =
'%s[%d].' % (name, i)
1285 sub_errors = element.FindInitializationErrors()
1286 errors += [prefix + error
for error
in sub_errors]
1289 sub_errors = value.FindInitializationErrors()
1290 errors += [prefix + error
for error
in sub_errors]
1294 cls.FindInitializationErrors = FindInitializationErrors
1298 module = klass.__module__
1299 name = getattr(klass,
'__qualname__', klass.__name__)
1300 if module
in (
None,
'builtins',
'__builtin__'):
1302 return module +
'.' + name
1306 LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED
1307 CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE
1310 if not isinstance(msg, cls):
1312 'Parameter to MergeFrom() must be instance of same class: '
1316 assert msg
is not self
1319 fields = self._fields
1321 for field, value
in msg._fields.items():
1322 if field.label == LABEL_REPEATED:
1323 field_value = fields.get(field)
1324 if field_value
is None:
1326 field_value = field._default_constructor(self)
1327 fields[field] = field_value
1328 field_value.MergeFrom(value)
1329 elif field.cpp_type == CPPTYPE_MESSAGE:
1330 if value._is_present_in_parent:
1331 field_value = fields.get(field)
1332 if field_value
is None:
1334 field_value = field._default_constructor(self)
1335 fields[field] = field_value
1336 field_value.MergeFrom(value)
1338 self._fields[field] = value
1339 if field.containing_oneof:
1340 self._UpdateOneofState(field)
1342 if msg._unknown_fields:
1343 if not self._unknown_fields:
1344 self._unknown_fields = []
1345 self._unknown_fields.extend(msg._unknown_fields)
1347 if self._unknown_field_set
is None:
1349 self._unknown_field_set._extend(msg._unknown_field_set)
1351 cls.MergeFrom = MergeFrom
1356 """Returns the name of the currently set field inside a oneof, or None."""
1358 field = message_descriptor.oneofs_by_name[oneof_name]
1361 'Protocol message has no oneof "%s" field.' % oneof_name)
1363 nested_field = self._oneofs.
get(field,
None)
1364 if nested_field
is not None and self.HasField(nested_field.name):
1365 return nested_field.name
1369 cls.WhichOneof = WhichOneof
1375 self._unknown_fields = ()
1377 if self._unknown_field_set
is not None:
1378 self._unknown_field_set._clear()
1379 self._unknown_field_set =
None
1386 if self._unknown_field_set
is None:
1389 return self._unknown_field_set
1393 self._unknown_fields = []
1394 self._unknown_field_set =
None
1395 for field, value
in self.ListFields():
1396 if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
1401 elif field.label == _FieldDescriptor.LABEL_REPEATED:
1402 for sub_message
in value:
1403 sub_message.DiscardUnknownFields()
1405 value.DiscardUnknownFields()
1409 if listener
is None:
1410 self._listener = message_listener_mod.NullMessageListener()
1412 self._listener = listener
1416 """Adds implementations of all Message methods to cls."""
1420 if message_descriptor.is_extendable:
1436 cls.UnknownFields = _UnknownFields
1437 cls.DiscardUnknownFields = _DiscardUnknownFields
1438 cls._SetListener = _SetListener
1442 """Adds implementation of private helper methods to cls."""
1445 """Sets the _cached_byte_size_dirty bit to true,
1446 and propagates this to our listener iff this was a state change.
1453 if not self._cached_byte_size_dirty:
1454 self._cached_byte_size_dirty =
True
1455 self._listener_for_children.dirty =
True
1456 self._is_present_in_parent =
True
1457 self._listener.Modified()
1460 """Sets field as the active field in its containing oneof.
1462 Will also delete currently active field in the oneof, if it is different
1463 from the argument. Does not mark the message as modified.
1465 other_field = self._oneofs.setdefault(field.containing_oneof, field)
1466 if other_field
is not field:
1467 del self._fields[other_field]
1468 self._oneofs[field.containing_oneof] = field
1470 cls._Modified = Modified
1471 cls.SetInParent = Modified
1472 cls._UpdateOneofState = _UpdateOneofState
1477 """MessageListener implementation that a parent message registers with its
1480 In order to support semantics like:
1482 foo.bar.baz.qux = 23
1483 assert foo.HasField('bar')
1485 ...child objects must have back references to their parents.
1486 This helper class is at the heart of this support.
1491 parent_message: The message whose _Modified() method we should call when
1492 we receive Modified() messages.
1498 if isinstance(parent_message, weakref.ProxyType):
1514 except ReferenceError:
1522 """Special listener implementation for setting composite oneof fields."""
1526 parent_message: The message whose _Modified() method we should call when
1527 we receive Modified() messages.
1528 field: The descriptor of the field being set in the parent message.
1530 super(_OneofListener, self).
__init__(parent_message)
1534 """Also updates the state of the containing oneof in the parent message."""
1537 super(_OneofListener, self).
Modified()
1538 except ReferenceError: