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

Side by Side Diff: third_party/google/protobuf/internal/cpp_message.py

Issue 1153333003: Added tools to retrieve CQ builders from a CQ config (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Addressed comments Created 5 years, 6 months 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
(Empty)
1 # Protocol Buffers - Google's data interchange format
2 # Copyright 2008 Google Inc. All rights reserved.
3 # http://code.google.com/p/protobuf/
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 """Contains helper functions used to create protocol message classes from
32 Descriptor objects at runtime backed by the protocol buffer C++ API.
33 """
34
35 __author__ = 'petar@google.com (Petar Petrov)'
36
37 import copy_reg
38 import operator
39 from google.protobuf.internal import _net_proto2___python
40 from google.protobuf.internal import enum_type_wrapper
41 from google.protobuf import message
42
43
44 _LABEL_REPEATED = _net_proto2___python.LABEL_REPEATED
45 _LABEL_OPTIONAL = _net_proto2___python.LABEL_OPTIONAL
46 _CPPTYPE_MESSAGE = _net_proto2___python.CPPTYPE_MESSAGE
47 _TYPE_MESSAGE = _net_proto2___python.TYPE_MESSAGE
48
49
50 def GetDescriptorPool():
51 """Creates a new DescriptorPool C++ object."""
52 return _net_proto2___python.NewCDescriptorPool()
53
54
55 _pool = GetDescriptorPool()
56
57
58 def GetFieldDescriptor(full_field_name):
59 """Searches for a field descriptor given a full field name."""
60 return _pool.FindFieldByName(full_field_name)
61
62
63 def BuildFile(content):
64 """Registers a new proto file in the underlying C++ descriptor pool."""
65 _net_proto2___python.BuildFile(content)
66
67
68 def GetExtensionDescriptor(full_extension_name):
69 """Searches for extension descriptor given a full field name."""
70 return _pool.FindExtensionByName(full_extension_name)
71
72
73 def NewCMessage(full_message_name):
74 """Creates a new C++ protocol message by its name."""
75 return _net_proto2___python.NewCMessage(full_message_name)
76
77
78 def ScalarProperty(cdescriptor):
79 """Returns a scalar property for the given descriptor."""
80
81 def Getter(self):
82 return self._cmsg.GetScalar(cdescriptor)
83
84 def Setter(self, value):
85 self._cmsg.SetScalar(cdescriptor, value)
86
87 return property(Getter, Setter)
88
89
90 def CompositeProperty(cdescriptor, message_type):
91 """Returns a Python property the given composite field."""
92
93 def Getter(self):
94 sub_message = self._composite_fields.get(cdescriptor.name, None)
95 if sub_message is None:
96 cmessage = self._cmsg.NewSubMessage(cdescriptor)
97 sub_message = message_type._concrete_class(__cmessage=cmessage)
98 self._composite_fields[cdescriptor.name] = sub_message
99 return sub_message
100
101 return property(Getter)
102
103
104 class RepeatedScalarContainer(object):
105 """Container for repeated scalar fields."""
106
107 __slots__ = ['_message', '_cfield_descriptor', '_cmsg']
108
109 def __init__(self, msg, cfield_descriptor):
110 self._message = msg
111 self._cmsg = msg._cmsg
112 self._cfield_descriptor = cfield_descriptor
113
114 def append(self, value):
115 self._cmsg.AddRepeatedScalar(
116 self._cfield_descriptor, value)
117
118 def extend(self, sequence):
119 for element in sequence:
120 self.append(element)
121
122 def insert(self, key, value):
123 values = self[slice(None, None, None)]
124 values.insert(key, value)
125 self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values)
126
127 def remove(self, value):
128 values = self[slice(None, None, None)]
129 values.remove(value)
130 self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values)
131
132 def __setitem__(self, key, value):
133 values = self[slice(None, None, None)]
134 values[key] = value
135 self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values)
136
137 def __getitem__(self, key):
138 return self._cmsg.GetRepeatedScalar(self._cfield_descriptor, key)
139
140 def __delitem__(self, key):
141 self._cmsg.DeleteRepeatedField(self._cfield_descriptor, key)
142
143 def __len__(self):
144 return len(self[slice(None, None, None)])
145
146 def __eq__(self, other):
147 if self is other:
148 return True
149 if not operator.isSequenceType(other):
150 raise TypeError(
151 'Can only compare repeated scalar fields against sequences.')
152 # We are presumably comparing against some other sequence type.
153 return other == self[slice(None, None, None)]
154
155 def __ne__(self, other):
156 return not self == other
157
158 def __hash__(self):
159 raise TypeError('unhashable object')
160
161 def sort(self, *args, **kwargs):
162 # Maintain compatibility with the previous interface.
163 if 'sort_function' in kwargs:
164 kwargs['cmp'] = kwargs.pop('sort_function')
165 self._cmsg.AssignRepeatedScalar(self._cfield_descriptor,
166 sorted(self, *args, **kwargs))
167
168
169 def RepeatedScalarProperty(cdescriptor):
170 """Returns a Python property the given repeated scalar field."""
171
172 def Getter(self):
173 container = self._composite_fields.get(cdescriptor.name, None)
174 if container is None:
175 container = RepeatedScalarContainer(self, cdescriptor)
176 self._composite_fields[cdescriptor.name] = container
177 return container
178
179 def Setter(self, new_value):
180 raise AttributeError('Assignment not allowed to repeated field '
181 '"%s" in protocol message object.' % cdescriptor.name)
182
183 doc = 'Magic attribute generated for "%s" proto field.' % cdescriptor.name
184 return property(Getter, Setter, doc=doc)
185
186
187 class RepeatedCompositeContainer(object):
188 """Container for repeated composite fields."""
189
190 __slots__ = ['_message', '_subclass', '_cfield_descriptor', '_cmsg']
191
192 def __init__(self, msg, cfield_descriptor, subclass):
193 self._message = msg
194 self._cmsg = msg._cmsg
195 self._subclass = subclass
196 self._cfield_descriptor = cfield_descriptor
197
198 def add(self, **kwargs):
199 cmessage = self._cmsg.AddMessage(self._cfield_descriptor)
200 return self._subclass(__cmessage=cmessage, __owner=self._message, **kwargs)
201
202 def extend(self, elem_seq):
203 """Extends by appending the given sequence of elements of the same type
204 as this one, copying each individual message.
205 """
206 for message in elem_seq:
207 self.add().MergeFrom(message)
208
209 def remove(self, value):
210 # TODO(protocol-devel): This is inefficient as it needs to generate a
211 # message pointer for each message only to do index(). Move this to a C++
212 # extension function.
213 self.__delitem__(self[slice(None, None, None)].index(value))
214
215 def MergeFrom(self, other):
216 for message in other[:]:
217 self.add().MergeFrom(message)
218
219 def __getitem__(self, key):
220 cmessages = self._cmsg.GetRepeatedMessage(
221 self._cfield_descriptor, key)
222 subclass = self._subclass
223 if not isinstance(cmessages, list):
224 return subclass(__cmessage=cmessages, __owner=self._message)
225
226 return [subclass(__cmessage=m, __owner=self._message) for m in cmessages]
227
228 def __delitem__(self, key):
229 self._cmsg.DeleteRepeatedField(
230 self._cfield_descriptor, key)
231
232 def __len__(self):
233 return self._cmsg.FieldLength(self._cfield_descriptor)
234
235 def __eq__(self, other):
236 """Compares the current instance with another one."""
237 if self is other:
238 return True
239 if not isinstance(other, self.__class__):
240 raise TypeError('Can only compare repeated composite fields against '
241 'other repeated composite fields.')
242 messages = self[slice(None, None, None)]
243 other_messages = other[slice(None, None, None)]
244 return messages == other_messages
245
246 def __hash__(self):
247 raise TypeError('unhashable object')
248
249 def sort(self, cmp=None, key=None, reverse=False, **kwargs):
250 # Maintain compatibility with the old interface.
251 if cmp is None and 'sort_function' in kwargs:
252 cmp = kwargs.pop('sort_function')
253
254 # The cmp function, if provided, is passed the results of the key function,
255 # so we only need to wrap one of them.
256 if key is None:
257 index_key = self.__getitem__
258 else:
259 index_key = lambda i: key(self[i])
260
261 # Sort the list of current indexes by the underlying object.
262 indexes = range(len(self))
263 indexes.sort(cmp=cmp, key=index_key, reverse=reverse)
264
265 # Apply the transposition.
266 for dest, src in enumerate(indexes):
267 if dest == src:
268 continue
269 self._cmsg.SwapRepeatedFieldElements(self._cfield_descriptor, dest, src)
270 # Don't swap the same value twice.
271 indexes[src] = src
272
273
274 def RepeatedCompositeProperty(cdescriptor, message_type):
275 """Returns a Python property for the given repeated composite field."""
276
277 def Getter(self):
278 container = self._composite_fields.get(cdescriptor.name, None)
279 if container is None:
280 container = RepeatedCompositeContainer(
281 self, cdescriptor, message_type._concrete_class)
282 self._composite_fields[cdescriptor.name] = container
283 return container
284
285 def Setter(self, new_value):
286 raise AttributeError('Assignment not allowed to repeated field '
287 '"%s" in protocol message object.' % cdescriptor.name)
288
289 doc = 'Magic attribute generated for "%s" proto field.' % cdescriptor.name
290 return property(Getter, Setter, doc=doc)
291
292
293 class ExtensionDict(object):
294 """Extension dictionary added to each protocol message."""
295
296 def __init__(self, msg):
297 self._message = msg
298 self._cmsg = msg._cmsg
299 self._values = {}
300
301 def __setitem__(self, extension, value):
302 from google.protobuf import descriptor
303 if not isinstance(extension, descriptor.FieldDescriptor):
304 raise KeyError('Bad extension %r.' % (extension,))
305 cdescriptor = extension._cdescriptor
306 if (cdescriptor.label != _LABEL_OPTIONAL or
307 cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
308 raise TypeError('Extension %r is repeated and/or a composite type.' % (
309 extension.full_name,))
310 self._cmsg.SetScalar(cdescriptor, value)
311 self._values[extension] = value
312
313 def __getitem__(self, extension):
314 from google.protobuf import descriptor
315 if not isinstance(extension, descriptor.FieldDescriptor):
316 raise KeyError('Bad extension %r.' % (extension,))
317
318 cdescriptor = extension._cdescriptor
319 if (cdescriptor.label != _LABEL_REPEATED and
320 cdescriptor.cpp_type != _CPPTYPE_MESSAGE):
321 return self._cmsg.GetScalar(cdescriptor)
322
323 ext = self._values.get(extension, None)
324 if ext is not None:
325 return ext
326
327 ext = self._CreateNewHandle(extension)
328 self._values[extension] = ext
329 return ext
330
331 def ClearExtension(self, extension):
332 from google.protobuf import descriptor
333 if not isinstance(extension, descriptor.FieldDescriptor):
334 raise KeyError('Bad extension %r.' % (extension,))
335 self._cmsg.ClearFieldByDescriptor(extension._cdescriptor)
336 if extension in self._values:
337 del self._values[extension]
338
339 def HasExtension(self, extension):
340 from google.protobuf import descriptor
341 if not isinstance(extension, descriptor.FieldDescriptor):
342 raise KeyError('Bad extension %r.' % (extension,))
343 return self._cmsg.HasFieldByDescriptor(extension._cdescriptor)
344
345 def _FindExtensionByName(self, name):
346 """Tries to find a known extension with the specified name.
347
348 Args:
349 name: Extension full name.
350
351 Returns:
352 Extension field descriptor.
353 """
354 return self._message._extensions_by_name.get(name, None)
355
356 def _CreateNewHandle(self, extension):
357 cdescriptor = extension._cdescriptor
358 if (cdescriptor.label != _LABEL_REPEATED and
359 cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
360 cmessage = self._cmsg.NewSubMessage(cdescriptor)
361 return extension.message_type._concrete_class(__cmessage=cmessage)
362
363 if cdescriptor.label == _LABEL_REPEATED:
364 if cdescriptor.cpp_type == _CPPTYPE_MESSAGE:
365 return RepeatedCompositeContainer(
366 self._message, cdescriptor, extension.message_type._concrete_class)
367 else:
368 return RepeatedScalarContainer(self._message, cdescriptor)
369 # This shouldn't happen!
370 assert False
371 return None
372
373
374 def NewMessage(bases, message_descriptor, dictionary):
375 """Creates a new protocol message *class*."""
376 _AddClassAttributesForNestedExtensions(message_descriptor, dictionary)
377 _AddEnumValues(message_descriptor, dictionary)
378 _AddDescriptors(message_descriptor, dictionary)
379 return bases
380
381
382 def InitMessage(message_descriptor, cls):
383 """Constructs a new message instance (called before instance's __init__)."""
384 cls._extensions_by_name = {}
385 _AddInitMethod(message_descriptor, cls)
386 _AddMessageMethods(message_descriptor, cls)
387 _AddPropertiesForExtensions(message_descriptor, cls)
388 copy_reg.pickle(cls, lambda obj: (cls, (), obj.__getstate__()))
389
390
391 def _AddDescriptors(message_descriptor, dictionary):
392 """Sets up a new protocol message class dictionary.
393
394 Args:
395 message_descriptor: A Descriptor instance describing this message type.
396 dictionary: Class dictionary to which we'll add a '__slots__' entry.
397 """
398 dictionary['__descriptors'] = {}
399 for field in message_descriptor.fields:
400 dictionary['__descriptors'][field.name] = GetFieldDescriptor(
401 field.full_name)
402
403 dictionary['__slots__'] = list(dictionary['__descriptors'].iterkeys()) + [
404 '_cmsg', '_owner', '_composite_fields', 'Extensions', '_HACK_REFCOUNTS']
405
406
407 def _AddEnumValues(message_descriptor, dictionary):
408 """Sets class-level attributes for all enum fields defined in this message.
409
410 Args:
411 message_descriptor: Descriptor object for this message type.
412 dictionary: Class dictionary that should be populated.
413 """
414 for enum_type in message_descriptor.enum_types:
415 dictionary[enum_type.name] = enum_type_wrapper.EnumTypeWrapper(enum_type)
416 for enum_value in enum_type.values:
417 dictionary[enum_value.name] = enum_value.number
418
419
420 def _AddClassAttributesForNestedExtensions(message_descriptor, dictionary):
421 """Adds class attributes for the nested extensions."""
422 extension_dict = message_descriptor.extensions_by_name
423 for extension_name, extension_field in extension_dict.iteritems():
424 assert extension_name not in dictionary
425 dictionary[extension_name] = extension_field
426
427
428 def _AddInitMethod(message_descriptor, cls):
429 """Adds an __init__ method to cls."""
430
431 # Create and attach message field properties to the message class.
432 # This can be done just once per message class, since property setters and
433 # getters are passed the message instance.
434 # This makes message instantiation extremely fast, and at the same time it
435 # doesn't require the creation of property objects for each message instance,
436 # which saves a lot of memory.
437 for field in message_descriptor.fields:
438 field_cdescriptor = cls.__descriptors[field.name]
439 if field.label == _LABEL_REPEATED:
440 if field.cpp_type == _CPPTYPE_MESSAGE:
441 value = RepeatedCompositeProperty(field_cdescriptor, field.message_type)
442 else:
443 value = RepeatedScalarProperty(field_cdescriptor)
444 elif field.cpp_type == _CPPTYPE_MESSAGE:
445 value = CompositeProperty(field_cdescriptor, field.message_type)
446 else:
447 value = ScalarProperty(field_cdescriptor)
448 setattr(cls, field.name, value)
449
450 # Attach a constant with the field number.
451 constant_name = field.name.upper() + '_FIELD_NUMBER'
452 setattr(cls, constant_name, field.number)
453
454 def Init(self, **kwargs):
455 """Message constructor."""
456 cmessage = kwargs.pop('__cmessage', None)
457 if cmessage:
458 self._cmsg = cmessage
459 else:
460 self._cmsg = NewCMessage(message_descriptor.full_name)
461
462 # Keep a reference to the owner, as the owner keeps a reference to the
463 # underlying protocol buffer message.
464 owner = kwargs.pop('__owner', None)
465 if owner:
466 self._owner = owner
467
468 if message_descriptor.is_extendable:
469 self.Extensions = ExtensionDict(self)
470 else:
471 # Reference counting in the C++ code is broken and depends on
472 # the Extensions reference to keep this object alive during unit
473 # tests (see b/4856052). Remove this once b/4945904 is fixed.
474 self._HACK_REFCOUNTS = self
475 self._composite_fields = {}
476
477 for field_name, field_value in kwargs.iteritems():
478 field_cdescriptor = self.__descriptors.get(field_name, None)
479 if not field_cdescriptor:
480 raise ValueError('Protocol message has no "%s" field.' % field_name)
481 if field_cdescriptor.label == _LABEL_REPEATED:
482 if field_cdescriptor.cpp_type == _CPPTYPE_MESSAGE:
483 field_name = getattr(self, field_name)
484 for val in field_value:
485 field_name.add().MergeFrom(val)
486 else:
487 getattr(self, field_name).extend(field_value)
488 elif field_cdescriptor.cpp_type == _CPPTYPE_MESSAGE:
489 getattr(self, field_name).MergeFrom(field_value)
490 else:
491 setattr(self, field_name, field_value)
492
493 Init.__module__ = None
494 Init.__doc__ = None
495 cls.__init__ = Init
496
497
498 def _IsMessageSetExtension(field):
499 """Checks if a field is a message set extension."""
500 return (field.is_extension and
501 field.containing_type.has_options and
502 field.containing_type.GetOptions().message_set_wire_format and
503 field.type == _TYPE_MESSAGE and
504 field.message_type == field.extension_scope and
505 field.label == _LABEL_OPTIONAL)
506
507
508 def _AddMessageMethods(message_descriptor, cls):
509 """Adds the methods to a protocol message class."""
510 if message_descriptor.is_extendable:
511
512 def ClearExtension(self, extension):
513 self.Extensions.ClearExtension(extension)
514
515 def HasExtension(self, extension):
516 return self.Extensions.HasExtension(extension)
517
518 def HasField(self, field_name):
519 return self._cmsg.HasField(field_name)
520
521 def ClearField(self, field_name):
522 child_cmessage = None
523 if field_name in self._composite_fields:
524 child_field = self._composite_fields[field_name]
525 del self._composite_fields[field_name]
526
527 child_cdescriptor = self.__descriptors[field_name]
528 # TODO(anuraag): Support clearing repeated message fields as well.
529 if (child_cdescriptor.label != _LABEL_REPEATED and
530 child_cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
531 child_field._owner = None
532 child_cmessage = child_field._cmsg
533
534 if child_cmessage is not None:
535 self._cmsg.ClearField(field_name, child_cmessage)
536 else:
537 self._cmsg.ClearField(field_name)
538
539 def Clear(self):
540 cmessages_to_release = []
541 for field_name, child_field in self._composite_fields.iteritems():
542 child_cdescriptor = self.__descriptors[field_name]
543 # TODO(anuraag): Support clearing repeated message fields as well.
544 if (child_cdescriptor.label != _LABEL_REPEATED and
545 child_cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
546 child_field._owner = None
547 cmessages_to_release.append((child_cdescriptor, child_field._cmsg))
548 self._composite_fields.clear()
549 self._cmsg.Clear(cmessages_to_release)
550
551 def IsInitialized(self, errors=None):
552 if self._cmsg.IsInitialized():
553 return True
554 if errors is not None:
555 errors.extend(self.FindInitializationErrors());
556 return False
557
558 def SerializeToString(self):
559 if not self.IsInitialized():
560 raise message.EncodeError(
561 'Message %s is missing required fields: %s' % (
562 self._cmsg.full_name, ','.join(self.FindInitializationErrors())))
563 return self._cmsg.SerializeToString()
564
565 def SerializePartialToString(self):
566 return self._cmsg.SerializePartialToString()
567
568 def ParseFromString(self, serialized):
569 self.Clear()
570 self.MergeFromString(serialized)
571
572 def MergeFromString(self, serialized):
573 byte_size = self._cmsg.MergeFromString(serialized)
574 if byte_size < 0:
575 raise message.DecodeError('Unable to merge from string.')
576 return byte_size
577
578 def MergeFrom(self, msg):
579 if not isinstance(msg, cls):
580 raise TypeError(
581 "Parameter to MergeFrom() must be instance of same class: "
582 "expected %s got %s." % (cls.__name__, type(msg).__name__))
583 self._cmsg.MergeFrom(msg._cmsg)
584
585 def CopyFrom(self, msg):
586 self._cmsg.CopyFrom(msg._cmsg)
587
588 def ByteSize(self):
589 return self._cmsg.ByteSize()
590
591 def SetInParent(self):
592 return self._cmsg.SetInParent()
593
594 def ListFields(self):
595 all_fields = []
596 field_list = self._cmsg.ListFields()
597 fields_by_name = cls.DESCRIPTOR.fields_by_name
598 for is_extension, field_name in field_list:
599 if is_extension:
600 extension = cls._extensions_by_name[field_name]
601 all_fields.append((extension, self.Extensions[extension]))
602 else:
603 field_descriptor = fields_by_name[field_name]
604 all_fields.append(
605 (field_descriptor, getattr(self, field_name)))
606 all_fields.sort(key=lambda item: item[0].number)
607 return all_fields
608
609 def FindInitializationErrors(self):
610 return self._cmsg.FindInitializationErrors()
611
612 def __str__(self):
613 return str(self._cmsg)
614
615 def __eq__(self, other):
616 if self is other:
617 return True
618 if not isinstance(other, self.__class__):
619 return False
620 return self.ListFields() == other.ListFields()
621
622 def __ne__(self, other):
623 return not self == other
624
625 def __hash__(self):
626 raise TypeError('unhashable object')
627
628 def __unicode__(self):
629 # Lazy import to prevent circular import when text_format imports this file.
630 from google.protobuf import text_format
631 return text_format.MessageToString(self, as_utf8=True).decode('utf-8')
632
633 # Attach the local methods to the message class.
634 for key, value in locals().copy().iteritems():
635 if key not in ('key', 'value', '__builtins__', '__name__', '__doc__'):
636 setattr(cls, key, value)
637
638 # Static methods:
639
640 def RegisterExtension(extension_handle):
641 extension_handle.containing_type = cls.DESCRIPTOR
642 cls._extensions_by_name[extension_handle.full_name] = extension_handle
643
644 if _IsMessageSetExtension(extension_handle):
645 # MessageSet extension. Also register under type name.
646 cls._extensions_by_name[
647 extension_handle.message_type.full_name] = extension_handle
648 cls.RegisterExtension = staticmethod(RegisterExtension)
649
650 def FromString(string):
651 msg = cls()
652 msg.MergeFromString(string)
653 return msg
654 cls.FromString = staticmethod(FromString)
655
656
657
658 def _AddPropertiesForExtensions(message_descriptor, cls):
659 """Adds properties for all fields in this protocol message type."""
660 extension_dict = message_descriptor.extensions_by_name
661 for extension_name, extension_field in extension_dict.iteritems():
662 constant_name = extension_name.upper() + '_FIELD_NUMBER'
663 setattr(cls, constant_name, extension_field.number)
OLDNEW
« no previous file with comments | « third_party/google/protobuf/internal/containers.py ('k') | third_party/google/protobuf/internal/decoder.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698