Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: third_party/protobuf/python/google/protobuf/internal/python_message.py

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Protocol Buffers - Google's data interchange format 1 # Protocol Buffers - Google's data interchange format
2 # Copyright 2008 Google Inc. All rights reserved. 2 # Copyright 2008 Google Inc. All rights reserved.
3 # https://developers.google.com/protocol-buffers/ 3 # https://developers.google.com/protocol-buffers/
4 # 4 #
5 # Redistribution and use in source and binary forms, with or without 5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are 6 # modification, are permitted provided that the following conditions are
7 # met: 7 # met:
8 # 8 #
9 # * Redistributions of source code must retain the above copyright 9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer. 10 # notice, this list of conditions and the following disclaimer.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 output by the protocol compiler at compile-time. 44 output by the protocol compiler at compile-time.
45 45
46 The upshot of all this is that the real implementation 46 The upshot of all this is that the real implementation
47 details for ALL pure-Python protocol buffers are *here in 47 details for ALL pure-Python protocol buffers are *here in
48 this file*. 48 this file*.
49 """ 49 """
50 50
51 __author__ = 'robinson@google.com (Will Robinson)' 51 __author__ = 'robinson@google.com (Will Robinson)'
52 52
53 from io import BytesIO 53 from io import BytesIO
54 import struct
54 import sys 55 import sys
55 import struct
56 import weakref 56 import weakref
57 57
58 import six 58 import six
59 try: 59 try:
60 import six.moves.copyreg as copyreg 60 import six.moves.copyreg as copyreg
61 except ImportError: 61 except ImportError:
62 # On some platforms, for example gMac, we run native Python because there is 62 # On some platforms, for example gMac, we run native Python because there is
63 # nothing like hermetic Python. This means lesser control on the system and 63 # nothing like hermetic Python. This means lesser control on the system and
64 # the six.moves package may be missing (is missing on 20150321 on gMac). Be 64 # the six.moves package may be missing (is missing on 20150321 on gMac). Be
65 # extra conservative and try to load the old replacement if it fails. 65 # extra conservative and try to load the old replacement if it fails.
66 import copy_reg as copyreg 66 try:
67 import copy_reg as copyreg #PY26
68 except ImportError:
69 import copyreg
67 70
68 # We use "as" to avoid name collisions with variables. 71 # We use "as" to avoid name collisions with variables.
69 from google.protobuf.internal import containers 72 from google.protobuf.internal import containers
70 from google.protobuf.internal import decoder 73 from google.protobuf.internal import decoder
71 from google.protobuf.internal import encoder 74 from google.protobuf.internal import encoder
72 from google.protobuf.internal import enum_type_wrapper 75 from google.protobuf.internal import enum_type_wrapper
73 from google.protobuf.internal import message_listener as message_listener_mod 76 from google.protobuf.internal import message_listener as message_listener_mod
74 from google.protobuf.internal import type_checkers 77 from google.protobuf.internal import type_checkers
75 from google.protobuf.internal import well_known_types 78 from google.protobuf.internal import well_known_types
76 from google.protobuf.internal import wire_format 79 from google.protobuf.internal import wire_format
77 from google.protobuf import descriptor as descriptor_mod 80 from google.protobuf import descriptor as descriptor_mod
78 from google.protobuf import message as message_mod 81 from google.protobuf import message as message_mod
79 from google.protobuf import symbol_database
80 from google.protobuf import text_format 82 from google.protobuf import text_format
81 83
82 _FieldDescriptor = descriptor_mod.FieldDescriptor 84 _FieldDescriptor = descriptor_mod.FieldDescriptor
83 _AnyFullTypeName = 'google.protobuf.Any' 85 _AnyFullTypeName = 'google.protobuf.Any'
84 86
85 87
86 class GeneratedProtocolMessageType(type): 88 class GeneratedProtocolMessageType(type):
87 89
88 """Metaclass for protocol message classes created at runtime from Descriptors. 90 """Metaclass for protocol message classes created at runtime from Descriptors.
89 91
90 We add implementations for all methods described in the Message class. We 92 We add implementations for all methods described in the Message class. We
91 also create properties to allow getting/setting all fields in the protocol 93 also create properties to allow getting/setting all fields in the protocol
92 message. Finally, we create slots to prevent users from accidentally 94 message. Finally, we create slots to prevent users from accidentally
93 "setting" nonexistent fields in the protocol message, which then wouldn't get 95 "setting" nonexistent fields in the protocol message, which then wouldn't get
94 serialized / deserialized properly. 96 serialized / deserialized properly.
95 97
96 The protocol compiler currently uses this metaclass to create protocol 98 The protocol compiler currently uses this metaclass to create protocol
97 message classes at runtime. Clients can also manually create their own 99 message classes at runtime. Clients can also manually create their own
98 classes at runtime, as in this example: 100 classes at runtime, as in this example:
99 101
100 mydescriptor = Descriptor(.....) 102 mydescriptor = Descriptor(.....)
101 class MyProtoClass(Message): 103 factory = symbol_database.Default()
102 __metaclass__ = GeneratedProtocolMessageType 104 factory.pool.AddDescriptor(mydescriptor)
103 DESCRIPTOR = mydescriptor 105 MyProtoClass = factory.GetPrototype(mydescriptor)
104 myproto_instance = MyProtoClass() 106 myproto_instance = MyProtoClass()
105 myproto.foo_field = 23 107 myproto.foo_field = 23
106 ... 108 ...
107
108 The above example will not work for nested types. If you wish to include them,
109 use reflection.MakeClass() instead of manually instantiating the class in
110 order to create the appropriate class structure.
111 """ 109 """
112 110
113 # Must be consistent with the protocol-compiler code in 111 # Must be consistent with the protocol-compiler code in
114 # proto2/compiler/internal/generator.*. 112 # proto2/compiler/internal/generator.*.
115 _DESCRIPTOR_KEY = 'DESCRIPTOR' 113 _DESCRIPTOR_KEY = 'DESCRIPTOR'
116 114
117 def __new__(cls, name, bases, dictionary): 115 def __new__(cls, name, bases, dictionary):
118 """Custom allocation for runtime-generated class types. 116 """Custom allocation for runtime-generated class types.
119 117
120 We override __new__ because this is apparently the only place 118 We override __new__ because this is apparently the only place
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 bases: Base classes of the class we're constructing. 155 bases: Base classes of the class we're constructing.
158 (Should be message.Message). We ignore this field, but 156 (Should be message.Message). We ignore this field, but
159 it's required by the metaclass protocol 157 it's required by the metaclass protocol
160 dictionary: The class dictionary of the class we're 158 dictionary: The class dictionary of the class we're
161 constructing. dictionary[_DESCRIPTOR_KEY] must contain 159 constructing. dictionary[_DESCRIPTOR_KEY] must contain
162 a Descriptor object describing this protocol message 160 a Descriptor object describing this protocol message
163 type. 161 type.
164 """ 162 """
165 descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] 163 descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
166 cls._decoders_by_tag = {} 164 cls._decoders_by_tag = {}
167 cls._extensions_by_name = {}
168 cls._extensions_by_number = {}
169 if (descriptor.has_options and 165 if (descriptor.has_options and
170 descriptor.GetOptions().message_set_wire_format): 166 descriptor.GetOptions().message_set_wire_format):
171 cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = ( 167 cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = (
172 decoder.MessageSetItemDecoder(cls._extensions_by_number), None) 168 decoder.MessageSetItemDecoder(descriptor), None)
173 169
174 # Attach stuff to each FieldDescriptor for quick lookup later on. 170 # Attach stuff to each FieldDescriptor for quick lookup later on.
175 for field in descriptor.fields: 171 for field in descriptor.fields:
176 _AttachFieldHelpers(cls, field) 172 _AttachFieldHelpers(cls, field)
177 173
178 descriptor._concrete_class = cls # pylint: disable=protected-access 174 descriptor._concrete_class = cls # pylint: disable=protected-access
179 _AddEnumValues(descriptor, cls) 175 _AddEnumValues(descriptor, cls)
180 _AddInitMethod(descriptor, cls) 176 _AddInitMethod(descriptor, cls)
181 _AddPropertiesForFields(descriptor, cls) 177 _AddPropertiesForFields(descriptor, cls)
182 _AddPropertiesForExtensions(descriptor, cls) 178 _AddPropertiesForExtensions(descriptor, cls)
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 if field.label != _FieldDescriptor.LABEL_REPEATED: 374 if field.label != _FieldDescriptor.LABEL_REPEATED:
379 raise ValueError('map_entry set on non-repeated field %s' % ( 375 raise ValueError('map_entry set on non-repeated field %s' % (
380 field.name)) 376 field.name))
381 fields_by_name = field.message_type.fields_by_name 377 fields_by_name = field.message_type.fields_by_name
382 key_checker = type_checkers.GetTypeChecker(fields_by_name['key']) 378 key_checker = type_checkers.GetTypeChecker(fields_by_name['key'])
383 379
384 value_field = fields_by_name['value'] 380 value_field = fields_by_name['value']
385 if _IsMessageMapField(field): 381 if _IsMessageMapField(field):
386 def MakeMessageMapDefault(message): 382 def MakeMessageMapDefault(message):
387 return containers.MessageMap( 383 return containers.MessageMap(
388 message._listener_for_children, value_field.message_type, key_checker) 384 message._listener_for_children, value_field.message_type, key_checker,
385 field.message_type)
389 return MakeMessageMapDefault 386 return MakeMessageMapDefault
390 else: 387 else:
391 value_checker = type_checkers.GetTypeChecker(value_field) 388 value_checker = type_checkers.GetTypeChecker(value_field)
392 def MakePrimitiveMapDefault(message): 389 def MakePrimitiveMapDefault(message):
393 return containers.ScalarMap( 390 return containers.ScalarMap(
394 message._listener_for_children, key_checker, value_checker) 391 message._listener_for_children, key_checker, value_checker,
392 field.message_type)
395 return MakePrimitiveMapDefault 393 return MakePrimitiveMapDefault
396 394
397 def _DefaultValueConstructorForField(field): 395 def _DefaultValueConstructorForField(field):
398 """Returns a function which returns a default value for a field. 396 """Returns a function which returns a default value for a field.
399 397
400 Args: 398 Args:
401 field: FieldDescriptor object for this field. 399 field: FieldDescriptor object for this field.
402 400
403 The returned function has one argument: 401 The returned function has one argument:
404 message: Message instance containing this field, or a weakref proxy 402 message: Message instance containing this field, or a weakref proxy
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 setattr(cls, property_name, property(getter, setter, doc=doc)) 738 setattr(cls, property_name, property(getter, setter, doc=doc))
741 739
742 740
743 def _AddPropertiesForExtensions(descriptor, cls): 741 def _AddPropertiesForExtensions(descriptor, cls):
744 """Adds properties for all fields in this protocol message type.""" 742 """Adds properties for all fields in this protocol message type."""
745 extension_dict = descriptor.extensions_by_name 743 extension_dict = descriptor.extensions_by_name
746 for extension_name, extension_field in extension_dict.items(): 744 for extension_name, extension_field in extension_dict.items():
747 constant_name = extension_name.upper() + "_FIELD_NUMBER" 745 constant_name = extension_name.upper() + "_FIELD_NUMBER"
748 setattr(cls, constant_name, extension_field.number) 746 setattr(cls, constant_name, extension_field.number)
749 747
748 # TODO(amauryfa): Migrate all users of these attributes to functions like
749 # pool.FindExtensionByNumber(descriptor).
750 if descriptor.file is not None:
751 # TODO(amauryfa): Use cls.MESSAGE_FACTORY.pool when available.
752 pool = descriptor.file.pool
753 cls._extensions_by_number = pool._extensions_by_number[descriptor]
754 cls._extensions_by_name = pool._extensions_by_name[descriptor]
750 755
751 def _AddStaticMethods(cls): 756 def _AddStaticMethods(cls):
752 # TODO(robinson): This probably needs to be thread-safe(?) 757 # TODO(robinson): This probably needs to be thread-safe(?)
753 def RegisterExtension(extension_handle): 758 def RegisterExtension(extension_handle):
754 extension_handle.containing_type = cls.DESCRIPTOR 759 extension_handle.containing_type = cls.DESCRIPTOR
760 # TODO(amauryfa): Use cls.MESSAGE_FACTORY.pool when available.
761 cls.DESCRIPTOR.file.pool.AddExtensionDescriptor(extension_handle)
755 _AttachFieldHelpers(cls, extension_handle) 762 _AttachFieldHelpers(cls, extension_handle)
756
757 # Try to insert our extension, failing if an extension with the same number
758 # already exists.
759 actual_handle = cls._extensions_by_number.setdefault(
760 extension_handle.number, extension_handle)
761 if actual_handle is not extension_handle:
762 raise AssertionError(
763 'Extensions "%s" and "%s" both try to extend message type "%s" with '
764 'field number %d.' %
765 (extension_handle.full_name, actual_handle.full_name,
766 cls.DESCRIPTOR.full_name, extension_handle.number))
767
768 cls._extensions_by_name[extension_handle.full_name] = extension_handle
769
770 handle = extension_handle # avoid line wrapping
771 if _IsMessageSetExtension(handle):
772 # MessageSet extension. Also register under type name.
773 cls._extensions_by_name[
774 extension_handle.message_type.full_name] = extension_handle
775
776 cls.RegisterExtension = staticmethod(RegisterExtension) 763 cls.RegisterExtension = staticmethod(RegisterExtension)
777 764
778 def FromString(s): 765 def FromString(s):
779 message = cls() 766 message = cls()
780 message.MergeFromString(s) 767 message.MergeFromString(s)
781 return message 768 return message
782 cls.FromString = staticmethod(FromString) 769 cls.FromString = staticmethod(FromString)
783 770
784 771
785 def _IsPresent(item): 772 def _IsPresent(item):
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 This internal method is differnt from public Any Unpack method which takes 906 This internal method is differnt from public Any Unpack method which takes
920 the target message as argument. _InternalUnpackAny method does not have 907 the target message as argument. _InternalUnpackAny method does not have
921 target message type and need to find the message type in descriptor pool. 908 target message type and need to find the message type in descriptor pool.
922 909
923 Args: 910 Args:
924 msg: An Any message to be unpacked. 911 msg: An Any message to be unpacked.
925 912
926 Returns: 913 Returns:
927 The unpacked message. 914 The unpacked message.
928 """ 915 """
916 # TODO(amauryfa): Don't use the factory of generated messages.
917 # To make Any work with custom factories, use the message factory of the
918 # parent message.
919 # pylint: disable=g-import-not-at-top
920 from google.protobuf import symbol_database
921 factory = symbol_database.Default()
922
929 type_url = msg.type_url 923 type_url = msg.type_url
930 db = symbol_database.Default()
931 924
932 if not type_url: 925 if not type_url:
933 return None 926 return None
934 927
935 # TODO(haberman): For now we just strip the hostname. Better logic will be 928 # TODO(haberman): For now we just strip the hostname. Better logic will be
936 # required. 929 # required.
937 type_name = type_url.split("/")[-1] 930 type_name = type_url.split('/')[-1]
938 descriptor = db.pool.FindMessageTypeByName(type_name) 931 descriptor = factory.pool.FindMessageTypeByName(type_name)
939 932
940 if descriptor is None: 933 if descriptor is None:
941 return None 934 return None
942 935
943 message_class = db.GetPrototype(descriptor) 936 message_class = factory.GetPrototype(descriptor)
944 message = message_class() 937 message = message_class()
945 938
946 message.ParseFromString(msg.value) 939 message.ParseFromString(msg.value)
947 return message 940 return message
948 941
942
949 def _AddEqualsMethod(message_descriptor, cls): 943 def _AddEqualsMethod(message_descriptor, cls):
950 """Helper for _AddMessageMethods().""" 944 """Helper for _AddMessageMethods()."""
951 def __eq__(self, other): 945 def __eq__(self, other):
952 if (not isinstance(other, message_mod.Message) or 946 if (not isinstance(other, message_mod.Message) or
953 other.DESCRIPTOR != self.DESCRIPTOR): 947 other.DESCRIPTOR != self.DESCRIPTOR):
954 return False 948 return False
955 949
956 if self is other: 950 if self is other:
957 return True 951 return True
958 952
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
1216 1210
1217 1211
1218 def _AddMergeFromMethod(cls): 1212 def _AddMergeFromMethod(cls):
1219 LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED 1213 LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED
1220 CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE 1214 CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE
1221 1215
1222 def MergeFrom(self, msg): 1216 def MergeFrom(self, msg):
1223 if not isinstance(msg, cls): 1217 if not isinstance(msg, cls):
1224 raise TypeError( 1218 raise TypeError(
1225 "Parameter to MergeFrom() must be instance of same class: " 1219 "Parameter to MergeFrom() must be instance of same class: "
1226 "expected %s got %s." % (cls.__name__, type(msg).__name__)) 1220 'expected %s got %s.' % (cls.__name__, msg.__class__.__name__))
1227 1221
1228 assert msg is not self 1222 assert msg is not self
1229 self._Modified() 1223 self._Modified()
1230 1224
1231 fields = self._fields 1225 fields = self._fields
1232 1226
1233 for field, value in msg._fields.items(): 1227 for field, value in msg._fields.items():
1234 if field.label == LABEL_REPEATED: 1228 if field.label == LABEL_REPEATED:
1235 field_value = fields.get(field) 1229 field_value = fields.get(field)
1236 if field_value is None: 1230 if field_value is None:
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
1539 def _FindExtensionByNumber(self, number): 1533 def _FindExtensionByNumber(self, number):
1540 """Tries to find a known extension with the field number. 1534 """Tries to find a known extension with the field number.
1541 1535
1542 Args: 1536 Args:
1543 number: Extension field number. 1537 number: Extension field number.
1544 1538
1545 Returns: 1539 Returns:
1546 Extension field descriptor. 1540 Extension field descriptor.
1547 """ 1541 """
1548 return self._extended_message._extensions_by_number.get(number, None) 1542 return self._extended_message._extensions_by_number.get(number, None)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698