1#!/usr/bin/env python
2#
3# Copyright 2010 Google Inc.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18"""Stand-alone implementation of in memory protocol messages.
19
20Public Classes:
21  Enum: Represents an enumerated type.
22  Variant: Hint for wire format to determine how to serialize.
23  Message: Base class for user defined messages.
24  IntegerField: Field for integer values.
25  FloatField: Field for float values.
26  BooleanField: Field for boolean values.
27  BytesField: Field for binary string values.
28  StringField: Field for UTF-8 string values.
29  MessageField: Field for other message type values.
30  EnumField: Field for enumerated type values.
31
32Public Exceptions (indentation indications class hierarchy):
33  EnumDefinitionError: Raised when enumeration is incorrectly defined.
34  FieldDefinitionError: Raised when field is incorrectly defined.
35    InvalidVariantError: Raised when variant is not compatible with field type.
36    InvalidDefaultError: Raised when default is not compatiable with field.
37    InvalidNumberError: Raised when field number is out of range or reserved.
38  MessageDefinitionError: Raised when message is incorrectly defined.
39    DuplicateNumberError: Raised when field has duplicate number with another.
40  ValidationError: Raised when a message or field is not valid.
41  DefinitionNotFoundError: Raised when definition not found.
42"""
43import six
44
45__author__ = 'rafek@google.com (Rafe Kaplan)'
46
47
48import types
49import weakref
50
51from . import util
52
53__all__ = ['MAX_ENUM_VALUE',
54           'MAX_FIELD_NUMBER',
55           'FIRST_RESERVED_FIELD_NUMBER',
56           'LAST_RESERVED_FIELD_NUMBER',
57
58           'Enum',
59           'Field',
60           'FieldList',
61           'Variant',
62           'Message',
63           'IntegerField',
64           'FloatField',
65           'BooleanField',
66           'BytesField',
67           'StringField',
68           'MessageField',
69           'EnumField',
70           'find_definition',
71
72           'Error',
73           'DecodeError',
74           'EncodeError',
75           'EnumDefinitionError',
76           'FieldDefinitionError',
77           'InvalidVariantError',
78           'InvalidDefaultError',
79           'InvalidNumberError',
80           'MessageDefinitionError',
81           'DuplicateNumberError',
82           'ValidationError',
83           'DefinitionNotFoundError',
84          ]
85
86
87# TODO(rafek): Add extended module test to ensure all exceptions
88# in services extends Error.
89Error = util.Error
90
91
92class EnumDefinitionError(Error):
93  """Enumeration definition error."""
94
95
96class FieldDefinitionError(Error):
97  """Field definition error."""
98
99
100class InvalidVariantError(FieldDefinitionError):
101  """Invalid variant provided to field."""
102
103
104class InvalidDefaultError(FieldDefinitionError):
105  """Invalid default provided to field."""
106
107
108class InvalidNumberError(FieldDefinitionError):
109  """Invalid number provided to field."""
110
111
112class MessageDefinitionError(Error):
113  """Message definition error."""
114
115
116class DuplicateNumberError(Error):
117  """Duplicate number assigned to field."""
118
119
120class DefinitionNotFoundError(Error):
121  """Raised when definition is not found."""
122
123
124class DecodeError(Error):
125  """Error found decoding message from encoded form."""
126
127
128class EncodeError(Error):
129  """Error found when encoding message."""
130
131
132class ValidationError(Error):
133  """Invalid value for message error."""
134
135  def __str__(self):
136    """Prints string with field name if present on exception."""
137    message = Error.__str__(self)
138    try:
139      field_name = self.field_name
140    except AttributeError:
141      return message
142    else:
143      return message
144
145
146# Attributes that are reserved by a class definition that
147# may not be used by either Enum or Message class definitions.
148_RESERVED_ATTRIBUTE_NAMES = frozenset(
149    ['__module__', '__doc__', '__qualname__'])
150
151_POST_INIT_FIELD_ATTRIBUTE_NAMES = frozenset(
152    ['name',
153     '_message_definition',
154     '_MessageField__type',
155     '_EnumField__type',
156     '_EnumField__resolved_default'])
157
158_POST_INIT_ATTRIBUTE_NAMES = frozenset(
159    ['_message_definition'])
160
161# Maximum enumeration value as defined by the protocol buffers standard.
162# All enum values must be less than or equal to this value.
163MAX_ENUM_VALUE = (2 ** 29) - 1
164
165# Maximum field number as defined by the protocol buffers standard.
166# All field numbers must be less than or equal to this value.
167MAX_FIELD_NUMBER = (2 ** 29) - 1
168
169# Field numbers between 19000 and 19999 inclusive are reserved by the
170# protobuf protocol and may not be used by fields.
171FIRST_RESERVED_FIELD_NUMBER = 19000
172LAST_RESERVED_FIELD_NUMBER = 19999
173
174
175class _DefinitionClass(type):
176  """Base meta-class used for definition meta-classes.
177
178  The Enum and Message definition classes share some basic functionality.
179  Both of these classes may be contained by a Message definition.  After
180  initialization, neither class may have attributes changed
181  except for the protected _message_definition attribute, and that attribute
182  may change only once.
183  """
184
185  __initialized = False
186
187  def __init__(cls, name, bases, dct):
188    """Constructor."""
189    type.__init__(cls, name, bases, dct)
190    # Base classes may never be initialized.
191    if cls.__bases__ != (object,):
192      cls.__initialized = True
193
194  def message_definition(cls):
195    """Get outer Message definition that contains this definition.
196
197    Returns:
198      Containing Message definition if definition is contained within one,
199      else None.
200    """
201    try:
202      return cls._message_definition()
203    except AttributeError:
204      return None
205
206  def __setattr__(cls, name, value):
207    """Overridden so that cannot set variables on definition classes after init.
208
209    Setting attributes on a class must work during the period of initialization
210    to set the enumation value class variables and build the name/number maps.
211    Once __init__ has set the __initialized flag to True prohibits setting any
212    more values on the class.  The class is in effect frozen.
213
214    Args:
215      name: Name of value to set.
216      value: Value to set.
217    """
218    if cls.__initialized and name not in _POST_INIT_ATTRIBUTE_NAMES:
219      raise AttributeError('May not change values: %s' % name)
220    else:
221      type.__setattr__(cls, name, value)
222
223  def __delattr__(cls, name):
224    """Overridden so that cannot delete varaibles on definition classes."""
225    raise TypeError('May not delete attributes on definition class')
226
227  def definition_name(cls):
228    """Helper method for creating definition name.
229
230    Names will be generated to include the classes package name, scope (if the
231    class is nested in another definition) and class name.
232
233    By default, the package name for a definition is derived from its module
234    name.  However, this value can be overriden by placing a 'package' attribute
235    in the module that contains the definition class.  For example:
236
237      package = 'some.alternate.package'
238
239      class MyMessage(Message):
240        ...
241
242      >>> MyMessage.definition_name()
243      some.alternate.package.MyMessage
244
245    Returns:
246      Dot-separated fully qualified name of definition.
247    """
248    outer_definition_name = cls.outer_definition_name()
249    if outer_definition_name is None:
250      return six.text_type(cls.__name__)
251    else:
252      return u'%s.%s' % (outer_definition_name, cls.__name__)
253
254  def outer_definition_name(cls):
255    """Helper method for creating outer definition name.
256
257    Returns:
258      If definition is nested, will return the outer definitions name, else the
259      package name.
260    """
261    outer_definition = cls.message_definition()
262    if not outer_definition:
263      return util.get_package_for_module(cls.__module__)
264    else:
265      return outer_definition.definition_name()
266
267  def definition_package(cls):
268    """Helper method for creating creating the package of a definition.
269
270    Returns:
271      Name of package that definition belongs to.
272    """
273    outer_definition = cls.message_definition()
274    if not outer_definition:
275      return util.get_package_for_module(cls.__module__)
276    else:
277      return outer_definition.definition_package()
278
279
280class _EnumClass(_DefinitionClass):
281  """Meta-class used for defining the Enum base class.
282
283  Meta-class enables very specific behavior for any defined Enum
284  class.  All attributes defined on an Enum sub-class must be integers.
285  Each attribute defined on an Enum sub-class is translated
286  into an instance of that sub-class, with the name of the attribute
287  as its name, and the number provided as its value.  It also ensures
288  that only one level of Enum class hierarchy is possible.  In other
289  words it is not possible to delcare sub-classes of sub-classes of
290  Enum.
291
292  This class also defines some functions in order to restrict the
293  behavior of the Enum class and its sub-classes.  It is not possible
294  to change the behavior of the Enum class in later classes since
295  any new classes may be defined with only integer values, and no methods.
296  """
297
298  def __init__(cls, name, bases, dct):
299    # Can only define one level of sub-classes below Enum.
300    if not (bases == (object,) or bases == (Enum,)):
301      raise EnumDefinitionError('Enum type %s may only inherit from Enum' %
302                                (name,))
303
304    cls.__by_number = {}
305    cls.__by_name = {}
306
307    # Enum base class does not need to be initialized or locked.
308    if bases != (object,):
309      # Replace integer with number.
310      for attribute, value in dct.items():
311
312        # Module will be in every enum class.
313        if attribute in _RESERVED_ATTRIBUTE_NAMES:
314          continue
315
316        # Reject anything that is not an int.
317        if not isinstance(value, six.integer_types):
318          raise EnumDefinitionError(
319              'May only use integers in Enum definitions.  Found: %s = %s' %
320              (attribute, value))
321
322        # Protocol buffer standard recommends non-negative values.
323        # Reject negative values.
324        if value < 0:
325          raise EnumDefinitionError(
326              'Must use non-negative enum values.  Found: %s = %d' %
327              (attribute, value))
328
329        if value > MAX_ENUM_VALUE:
330          raise EnumDefinitionError(
331              'Must use enum values less than or equal %d.  Found: %s = %d' %
332              (MAX_ENUM_VALUE, attribute, value))
333
334        if value in cls.__by_number:
335          raise EnumDefinitionError(
336              'Value for %s = %d is already defined: %s' %
337              (attribute, value, cls.__by_number[value].name))
338
339        # Create enum instance and list in new Enum type.
340        instance = object.__new__(cls)
341        cls.__init__(instance, attribute, value)
342        cls.__by_name[instance.name] = instance
343        cls.__by_number[instance.number] = instance
344        setattr(cls, attribute, instance)
345
346    _DefinitionClass.__init__(cls, name, bases, dct)
347
348  def __iter__(cls):
349    """Iterate over all values of enum.
350
351    Yields:
352      Enumeration instances of the Enum class in arbitrary order.
353    """
354    return iter(cls.__by_number.values())
355
356  def names(cls):
357    """Get all names for Enum.
358
359    Returns:
360      An iterator for names of the enumeration in arbitrary order.
361    """
362    return cls.__by_name.keys()
363
364  def numbers(cls):
365    """Get all numbers for Enum.
366
367    Returns:
368      An iterator for all numbers of the enumeration in arbitrary order.
369    """
370    return cls.__by_number.keys()
371
372  def lookup_by_name(cls, name):
373    """Look up Enum by name.
374
375    Args:
376      name: Name of enum to find.
377
378    Returns:
379      Enum sub-class instance of that value.
380    """
381    return cls.__by_name[name]
382
383  def lookup_by_number(cls, number):
384    """Look up Enum by number.
385
386    Args:
387      number: Number of enum to find.
388
389    Returns:
390      Enum sub-class instance of that value.
391    """
392    return cls.__by_number[number]
393
394  def __len__(cls):
395    return len(cls.__by_name)
396
397
398class Enum(six.with_metaclass(_EnumClass, object)):
399  """Base class for all enumerated types."""
400
401  __slots__ = set(('name', 'number'))
402
403  def __new__(cls, index):
404    """Acts as look-up routine after class is initialized.
405
406    The purpose of overriding __new__ is to provide a way to treat
407    Enum subclasses as casting types, similar to how the int type
408    functions.  A program can pass a string or an integer and this
409    method with "convert" that value in to an appropriate Enum instance.
410
411    Args:
412      index: Name or number to look up.  During initialization
413        this is always the name of the new enum value.
414
415    Raises:
416      TypeError: When an inappropriate index value is passed provided.
417    """
418    # If is enum type of this class, return it.
419    if isinstance(index, cls):
420      return index
421
422    # If number, look up by number.
423    if isinstance(index, six.integer_types):
424      try:
425        return cls.lookup_by_number(index)
426      except KeyError:
427        pass
428
429    # If name, look up by name.
430    if isinstance(index, six.string_types):
431      try:
432        return cls.lookup_by_name(index)
433      except KeyError:
434        pass
435
436    raise TypeError('No such value for %s in Enum %s' %
437                    (index, cls.__name__))
438
439  def __init__(self, name, number=None):
440    """Initialize new Enum instance.
441
442    Since this should only be called during class initialization any
443    calls that happen after the class is frozen raises an exception.
444    """
445    # Immediately return if __init__ was called after _Enum.__init__().
446    # It means that casting operator version of the class constructor
447    # is being used.
448    if getattr(type(self), '_DefinitionClass__initialized'):
449      return
450    object.__setattr__(self, 'name', name)
451    object.__setattr__(self, 'number', number)
452
453  def __setattr__(self, name, value):
454    raise TypeError('May not change enum values')
455
456  def __str__(self):
457    return self.name
458
459  def __int__(self):
460    return self.number
461
462  def __repr__(self):
463    return '%s(%s, %d)' % (type(self).__name__, self.name, self.number)
464
465  def __reduce__(self):
466    """Enable pickling.
467
468    Returns:
469      A 2-tuple containing the class and __new__ args to be used for restoring
470      a pickled instance.
471    """
472    return self.__class__, (self.number,)
473
474  def __cmp__(self, other):
475    """Order is by number."""
476    if isinstance(other, type(self)):
477      return cmp(self.number, other.number)
478    return NotImplemented
479
480  def __lt__(self, other):
481    """Order is by number."""
482    if isinstance(other, type(self)):
483      return self.number < other.number
484    return NotImplemented
485
486  def __le__(self, other):
487    """Order is by number."""
488    if isinstance(other, type(self)):
489      return self.number <= other.number
490    return NotImplemented
491
492  def __eq__(self, other):
493    """Order is by number."""
494    if isinstance(other, type(self)):
495      return self.number == other.number
496    return NotImplemented
497
498  def __ne__(self, other):
499    """Order is by number."""
500    if isinstance(other, type(self)):
501      return self.number != other.number
502    return NotImplemented
503
504  def __ge__(self, other):
505    """Order is by number."""
506    if isinstance(other, type(self)):
507      return self.number >= other.number
508    return NotImplemented
509
510  def __gt__(self, other):
511    """Order is by number."""
512    if isinstance(other, type(self)):
513      return self.number > other.number
514    return NotImplemented
515
516  def __hash__(self):
517    """Hash by number."""
518    return hash(self.number)
519
520  @classmethod
521  def to_dict(cls):
522    """Make dictionary version of enumerated class.
523
524    Dictionary created this way can be used with def_num.
525
526    Returns:
527      A dict (name) -> number
528    """
529    return dict((item.name, item.number) for item in iter(cls))
530
531  @staticmethod
532  def def_enum(dct, name):
533    """Define enum class from dictionary.
534
535    Args:
536      dct: Dictionary of enumerated values for type.
537      name: Name of enum.
538    """
539    return type(name, (Enum,), dct)
540
541
542# TODO(rafek): Determine to what degree this enumeration should be compatible
543# with FieldDescriptor.Type in:
544#
545#   http://code.google.com/p/protobuf/source/browse/trunk/src/google/protobuf/descriptor.proto
546class Variant(Enum):
547  """Wire format variant.
548
549  Used by the 'protobuf' wire format to determine how to transmit
550  a single piece of data.  May be used by other formats.
551
552  See: http://code.google.com/apis/protocolbuffers/docs/encoding.html
553
554  Values:
555    DOUBLE: 64-bit floating point number.
556    FLOAT: 32-bit floating point number.
557    INT64: 64-bit signed integer.
558    UINT64: 64-bit unsigned integer.
559    INT32: 32-bit signed integer.
560    BOOL: Boolean value (True or False).
561    STRING: String of UTF-8 encoded text.
562    MESSAGE: Embedded message as byte string.
563    BYTES: String of 8-bit bytes.
564    UINT32: 32-bit unsigned integer.
565    ENUM: Enum value as integer.
566    SINT32: 32-bit signed integer.  Uses "zig-zag" encoding.
567    SINT64: 64-bit signed integer.  Uses "zig-zag" encoding.
568  """
569  DOUBLE   = 1
570  FLOAT    = 2
571  INT64    = 3
572  UINT64   = 4
573  INT32    = 5
574  BOOL     = 8
575  STRING   = 9
576  MESSAGE  = 11
577  BYTES    = 12
578  UINT32   = 13
579  ENUM     = 14
580  SINT32   = 17
581  SINT64   = 18
582
583
584class _MessageClass(_DefinitionClass):
585  """Meta-class used for defining the Message base class.
586
587  For more details about Message classes, see the Message class docstring.
588  Information contained there may help understanding this class.
589
590  Meta-class enables very specific behavior for any defined Message
591  class.  All attributes defined on an Message sub-class must be field
592  instances, Enum class definitions or other Message class definitions.  Each
593  field attribute defined on an Message sub-class is added to the set of
594  field definitions and the attribute is translated in to a slot.  It also
595  ensures that only one level of Message class hierarchy is possible.  In other
596  words it is not possible to declare sub-classes of sub-classes of
597  Message.
598
599  This class also defines some functions in order to restrict the
600  behavior of the Message class and its sub-classes.  It is not possible
601  to change the behavior of the Message class in later classes since
602  any new classes may be defined with only field, Enums and Messages, and
603  no methods.
604  """
605
606  def __new__(cls, name, bases, dct):
607    """Create new Message class instance.
608
609    The __new__ method of the _MessageClass type is overridden so as to
610    allow the translation of Field instances to slots.
611    """
612    by_number = {}
613    by_name = {}
614
615    variant_map = {}
616
617    if bases != (object,):
618      # Can only define one level of sub-classes below Message.
619      if bases != (Message,):
620        raise MessageDefinitionError(
621            'Message types may only inherit from Message')
622
623      enums = []
624      messages = []
625      # Must not use iteritems because this loop will change the state of dct.
626      for key, field in dct.items():
627
628        if key in _RESERVED_ATTRIBUTE_NAMES:
629          continue
630
631        if isinstance(field, type) and issubclass(field, Enum):
632          enums.append(key)
633          continue
634
635        if (isinstance(field, type) and
636            issubclass(field, Message) and
637            field is not Message):
638          messages.append(key)
639          continue
640
641        # Reject anything that is not a field.
642        if type(field) is Field or not isinstance(field, Field):
643          raise MessageDefinitionError(
644              'May only use fields in message definitions.  Found: %s = %s' %
645              (key, field))
646
647        if field.number in by_number:
648          raise DuplicateNumberError(
649              'Field with number %d declared more than once in %s' %
650              (field.number, name))
651
652        field.name = key
653
654        # Place in name and number maps.
655        by_name[key] = field
656        by_number[field.number] = field
657
658      # Add enums if any exist.
659      if enums:
660        dct['__enums__'] = sorted(enums)
661
662      # Add messages if any exist.
663      if messages:
664        dct['__messages__'] = sorted(messages)
665
666    dct['_Message__by_number'] = by_number
667    dct['_Message__by_name'] = by_name
668
669    return _DefinitionClass.__new__(cls, name, bases, dct)
670
671  def __init__(cls, name, bases, dct):
672    """Initializer required to assign references to new class."""
673    if bases != (object,):
674      for value in dct.values():
675        if isinstance(value, _DefinitionClass) and not value is Message:
676          value._message_definition = weakref.ref(cls)
677
678      for field in cls.all_fields():
679        field._message_definition = weakref.ref(cls)
680
681    _DefinitionClass.__init__(cls, name, bases, dct)
682
683
684class Message(six.with_metaclass(_MessageClass, object)):
685  """Base class for user defined message objects.
686
687  Used to define messages for efficient transmission across network or
688  process space.  Messages are defined using the field classes (IntegerField,
689  FloatField, EnumField, etc.).
690
691  Messages are more restricted than normal classes in that they may only
692  contain field attributes and other Message and Enum definitions.  These
693  restrictions are in place because the structure of the Message class is
694  intentended to itself be transmitted across network or process space and
695  used directly by clients or even other servers.  As such methods and
696  non-field attributes could not be transmitted with the structural information
697  causing discrepancies between different languages and implementations.
698
699  Initialization and validation:
700
701    A Message object is considered to be initialized if it has all required
702    fields and any nested messages are also initialized.
703
704    Calling 'check_initialized' will raise a ValidationException if it is not
705    initialized; 'is_initialized' returns a boolean value indicating if it is
706    valid.
707
708    Validation automatically occurs when Message objects are created
709    and populated.  Validation that a given value will be compatible with
710    a field that it is assigned to can be done through the Field instances
711    validate() method.  The validate method used on a message will check that
712    all values of a message and its sub-messages are valid.  Assingning an
713    invalid value to a field will raise a ValidationException.
714
715  Example:
716
717    # Trade type.
718    class TradeType(Enum):
719      BUY = 1
720      SELL = 2
721      SHORT = 3
722      CALL = 4
723
724    class Lot(Message):
725      price = IntegerField(1, required=True)
726      quantity = IntegerField(2, required=True)
727
728    class Order(Message):
729      symbol = StringField(1, required=True)
730      total_quantity = IntegerField(2, required=True)
731      trade_type = EnumField(TradeType, 3, required=True)
732      lots = MessageField(Lot, 4, repeated=True)
733      limit = IntegerField(5)
734
735    order = Order(symbol='GOOG',
736                  total_quantity=10,
737                  trade_type=TradeType.BUY)
738
739    lot1 = Lot(price=304,
740               quantity=7)
741
742    lot2 = Lot(price = 305,
743               quantity=3)
744
745    order.lots = [lot1, lot2]
746
747    # Now object is initialized!
748    order.check_initialized()
749  """
750
751  def __init__(self, **kwargs):
752    """Initialize internal messages state.
753
754    Args:
755      A message can be initialized via the constructor by passing in keyword
756      arguments corresponding to fields.  For example:
757
758        class Date(Message):
759          day = IntegerField(1)
760          month = IntegerField(2)
761          year = IntegerField(3)
762
763      Invoking:
764
765        date = Date(day=6, month=6, year=1911)
766
767      is the same as doing:
768
769        date = Date()
770        date.day = 6
771        date.month = 6
772        date.year = 1911
773    """
774    # Tag being an essential implementation detail must be private.
775    self.__tags = {}
776    self.__unrecognized_fields = {}
777
778    assigned = set()
779    for name, value in kwargs.items():
780      setattr(self, name, value)
781      assigned.add(name)
782
783    # initialize repeated fields.
784    for field in self.all_fields():
785      if field.repeated and field.name not in assigned:
786        setattr(self, field.name, [])
787
788
789  def check_initialized(self):
790    """Check class for initialization status.
791
792    Check that all required fields are initialized
793
794    Raises:
795      ValidationError: If message is not initialized.
796    """
797    for name, field in self.__by_name.items():
798      value = getattr(self, name)
799      if value is None:
800        if field.required:
801          raise ValidationError("Message %s is missing required field %s" %
802                                (type(self).__name__, name))
803      else:
804        try:
805          if (isinstance(field, MessageField) and
806              issubclass(field.message_type, Message)):
807            if field.repeated:
808              for item in value:
809                item_message_value = field.value_to_message(item)
810                item_message_value.check_initialized()
811            else:
812              message_value = field.value_to_message(value)
813              message_value.check_initialized()
814        except ValidationError as err:
815          if not hasattr(err, 'message_name'):
816            err.message_name = type(self).__name__
817          raise
818
819  def is_initialized(self):
820    """Get initialization status.
821
822    Returns:
823      True if message is valid, else False.
824    """
825    try:
826      self.check_initialized()
827    except ValidationError:
828      return False
829    else:
830      return True
831
832  @classmethod
833  def all_fields(cls):
834    """Get all field definition objects.
835
836    Ordering is arbitrary.
837
838    Returns:
839      Iterator over all values in arbitrary order.
840    """
841    return cls.__by_name.values()
842
843  @classmethod
844  def field_by_name(cls, name):
845    """Get field by name.
846
847    Returns:
848      Field object associated with name.
849
850    Raises:
851      KeyError if no field found by that name.
852    """
853    return cls.__by_name[name]
854
855  @classmethod
856  def field_by_number(cls, number):
857    """Get field by number.
858
859    Returns:
860      Field object associated with number.
861
862    Raises:
863      KeyError if no field found by that number.
864    """
865    return cls.__by_number[number]
866
867  def get_assigned_value(self, name):
868    """Get the assigned value of an attribute.
869
870    Get the underlying value of an attribute.  If value has not been set, will
871    not return the default for the field.
872
873    Args:
874      name: Name of attribute to get.
875
876    Returns:
877      Value of attribute, None if it has not been set.
878    """
879    message_type = type(self)
880    try:
881      field = message_type.field_by_name(name)
882    except KeyError:
883      raise AttributeError('Message %s has no field %s' % (
884          message_type.__name__, name))
885    return self.__tags.get(field.number)
886
887  def reset(self, name):
888    """Reset assigned value for field.
889
890    Resetting a field will return it to its default value or None.
891
892    Args:
893      name: Name of field to reset.
894    """
895    message_type = type(self)
896    try:
897      field = message_type.field_by_name(name)
898    except KeyError:
899      if name not in message_type.__by_name:
900        raise AttributeError('Message %s has no field %s' % (
901            message_type.__name__, name))
902    if field.repeated:
903      self.__tags[field.number] = FieldList(field, [])
904    else:
905      self.__tags.pop(field.number, None)
906
907  def all_unrecognized_fields(self):
908    """Get the names of all unrecognized fields in this message."""
909    return list(self.__unrecognized_fields.keys())
910
911  def get_unrecognized_field_info(self, key, value_default=None,
912                                  variant_default=None):
913    """Get the value and variant of an unknown field in this message.
914
915    Args:
916      key: The name or number of the field to retrieve.
917      value_default: Value to be returned if the key isn't found.
918      variant_default: Value to be returned as variant if the key isn't
919        found.
920
921    Returns:
922      (value, variant), where value and variant are whatever was passed
923      to set_unrecognized_field.
924    """
925    value, variant = self.__unrecognized_fields.get(key, (value_default,
926                                                          variant_default))
927    return value, variant
928
929  def set_unrecognized_field(self, key, value, variant):
930    """Set an unrecognized field, used when decoding a message.
931
932    Args:
933      key: The name or number used to refer to this unknown value.
934      value: The value of the field.
935      variant: Type information needed to interpret the value or re-encode it.
936
937    Raises:
938      TypeError: If the variant is not an instance of messages.Variant.
939    """
940    if not isinstance(variant, Variant):
941      raise TypeError('Variant type %s is not valid.' % variant)
942    self.__unrecognized_fields[key] = value, variant
943
944  def __setattr__(self, name, value):
945    """Change set behavior for messages.
946
947    Messages may only be assigned values that are fields.
948
949    Does not try to validate field when set.
950
951    Args:
952      name: Name of field to assign to.
953      vlaue: Value to assign to field.
954
955    Raises:
956      AttributeError when trying to assign value that is not a field.
957    """
958    if name in self.__by_name or name.startswith('_Message__'):
959      object.__setattr__(self, name, value)
960    else:
961      raise AttributeError("May not assign arbitrary value %s "
962                           "to message %s" % (name, type(self).__name__))
963
964  def __repr__(self):
965    """Make string representation of message.
966
967    Example:
968
969      class MyMessage(messages.Message):
970        integer_value = messages.IntegerField(1)
971        string_value = messages.StringField(2)
972
973      my_message = MyMessage()
974      my_message.integer_value = 42
975      my_message.string_value = u'A string'
976
977      print my_message
978      >>> <MyMessage
979      ...  integer_value: 42
980      ...  string_value: u'A string'>
981
982    Returns:
983      String representation of message, including the values
984      of all fields and repr of all sub-messages.
985    """
986    body = ['<', type(self).__name__]
987    for field in sorted(self.all_fields(),
988                        key=lambda f: f.number):
989      attribute = field.name
990      value = self.get_assigned_value(field.name)
991      if value is not None:
992        body.append('\n %s: %s' % (attribute, repr(value)))
993    body.append('>')
994    return ''.join(body)
995
996  def __eq__(self, other):
997    """Equality operator.
998
999    Does field by field comparison with other message.  For
1000    equality, must be same type and values of all fields must be
1001    equal.
1002
1003    Messages not required to be initialized for comparison.
1004
1005    Does not attempt to determine equality for values that have
1006    default values that are not set.  In other words:
1007
1008      class HasDefault(Message):
1009
1010        attr1 = StringField(1, default='default value')
1011
1012      message1 = HasDefault()
1013      message2 = HasDefault()
1014      message2.attr1 = 'default value'
1015
1016      message1 != message2
1017
1018    Does not compare unknown values.
1019
1020    Args:
1021      other: Other message to compare with.
1022    """
1023    # TODO(rafek): Implement "equivalent" which does comparisons
1024    # taking default values in to consideration.
1025    if self is other:
1026      return True
1027
1028    if type(self) is not type(other):
1029      return False
1030
1031    return self.__tags == other.__tags
1032
1033  def __ne__(self, other):
1034    """Not equals operator.
1035
1036    Does field by field comparison with other message.  For
1037    non-equality, must be different type or any value of a field must be
1038    non-equal to the same field in the other instance.
1039
1040    Messages not required to be initialized for comparison.
1041
1042    Args:
1043      other: Other message to compare with.
1044    """
1045    return not self.__eq__(other)
1046
1047
1048class FieldList(list):
1049  """List implementation that validates field values.
1050
1051  This list implementation overrides all methods that add values in to a list
1052  in order to validate those new elements.  Attempting to add or set list
1053  values that are not of the correct type will raise ValidationError.
1054  """
1055
1056  def __init__(self, field_instance, sequence):
1057    """Constructor.
1058
1059    Args:
1060      field_instance: Instance of field that validates the list.
1061      sequence: List or tuple to construct list from.
1062    """
1063    if not field_instance.repeated:
1064      raise FieldDefinitionError('FieldList may only accept repeated fields')
1065    self.__field = field_instance
1066    self.__field.validate(sequence)
1067    list.__init__(self, sequence)
1068
1069  def __getstate__(self):
1070    """Enable pickling.
1071
1072    The assigned field instance can't be pickled if it belongs to a Message
1073    definition (message_definition uses a weakref), so the Message class and
1074    field number are returned in that case.
1075
1076    Returns:
1077      A 3-tuple containing:
1078        - The field instance, or None if it belongs to a Message class.
1079        - The Message class that the field instance belongs to, or None.
1080        - The field instance number of the Message class it belongs to, or None.
1081    """
1082    message_class = self.__field.message_definition()
1083    if message_class is None:
1084      return self.__field, None, None
1085    else:
1086      return None, message_class, self.__field.number
1087
1088  def __setstate__(self, state):
1089    """Enable unpickling.
1090
1091    Args:
1092      state: A 3-tuple containing:
1093        - The field instance, or None if it belongs to a Message class.
1094        - The Message class that the field instance belongs to, or None.
1095        - The field instance number of the Message class it belongs to, or None.
1096    """
1097    field_instance, message_class, number = state
1098    if field_instance is None:
1099      self.__field = message_class.field_by_number(number)
1100    else:
1101      self.__field = field_instance
1102
1103  @property
1104  def field(self):
1105    """Field that validates list."""
1106    return self.__field
1107
1108  def __setslice__(self, i, j, sequence):
1109    """Validate slice assignment to list."""
1110    self.__field.validate(sequence)
1111    list.__setslice__(self, i, j, sequence)
1112
1113  def __setitem__(self, index, value):
1114    """Validate item assignment to list."""
1115    if isinstance(index, slice):
1116        self.__field.validate(value)
1117    else:
1118        self.__field.validate_element(value)
1119    list.__setitem__(self, index, value)
1120
1121  def append(self, value):
1122    """Validate item appending to list."""
1123    self.__field.validate_element(value)
1124    return list.append(self, value)
1125
1126  def extend(self, sequence):
1127    """Validate extension of list."""
1128    self.__field.validate(sequence)
1129    return list.extend(self, sequence)
1130
1131  def insert(self, index, value):
1132    """Validate item insertion to list."""
1133    self.__field.validate_element(value)
1134    return list.insert(self, index, value)
1135
1136
1137# TODO(rafek): Prevent additional field subclasses.
1138class Field(object):
1139
1140  __variant_to_type = {}
1141
1142  class __metaclass__(type):
1143
1144    def __init__(cls, name, bases, dct):
1145      getattr(cls, '_Field__variant_to_type').update(
1146        (variant, cls) for variant in dct.get('VARIANTS', []))
1147      type.__init__(cls, name, bases, dct)
1148
1149  __initialized = False
1150
1151  @util.positional(2)
1152  def __init__(self,
1153               number,
1154               required=False,
1155               repeated=False,
1156               variant=None,
1157               default=None):
1158    """Constructor.
1159
1160    The required and repeated parameters are mutually exclusive.  Setting both
1161    to True will raise a FieldDefinitionError.
1162
1163    Sub-class Attributes:
1164      Each sub-class of Field must define the following:
1165        VARIANTS: Set of variant types accepted by that field.
1166        DEFAULT_VARIANT: Default variant type if not specified in constructor.
1167
1168    Args:
1169      number: Number of field.  Must be unique per message class.
1170      required: Whether or not field is required.  Mutually exclusive with
1171        'repeated'.
1172      repeated: Whether or not field is repeated.  Mutually exclusive with
1173        'required'.
1174      variant: Wire-format variant hint.
1175      default: Default value for field if not found in stream.
1176
1177    Raises:
1178      InvalidVariantError when invalid variant for field is provided.
1179      InvalidDefaultError when invalid default for field is provided.
1180      FieldDefinitionError when invalid number provided or mutually exclusive
1181        fields are used.
1182      InvalidNumberError when the field number is out of range or reserved.
1183    """
1184    if not isinstance(number, int) or not 1 <= number <= MAX_FIELD_NUMBER:
1185      raise InvalidNumberError('Invalid number for field: %s\n'
1186                               'Number must be 1 or greater and %d or less' %
1187                               (number, MAX_FIELD_NUMBER))
1188
1189    if FIRST_RESERVED_FIELD_NUMBER <= number <= LAST_RESERVED_FIELD_NUMBER:
1190      raise InvalidNumberError('Tag number %d is a reserved number.\n'
1191                               'Numbers %d to %d are reserved' %
1192                               (number, FIRST_RESERVED_FIELD_NUMBER,
1193                                LAST_RESERVED_FIELD_NUMBER))
1194
1195    if repeated and required:
1196      raise FieldDefinitionError('Cannot set both repeated and required')
1197
1198    if variant is None:
1199      variant = self.DEFAULT_VARIANT
1200
1201    if repeated and default is not None:
1202      raise FieldDefinitionError('Repeated fields may not have defaults')
1203
1204    if variant not in self.VARIANTS:
1205      raise InvalidVariantError(
1206          'Invalid variant: %s\nValid variants for %s are %r' %
1207          (variant, type(self).__name__, sorted(self.VARIANTS)))
1208
1209    self.number = number
1210    self.required = required
1211    self.repeated = repeated
1212    self.variant = variant
1213
1214    if default is not None:
1215      try:
1216        self.validate_default(default)
1217      except ValidationError as err:
1218        try:
1219          name = self.name
1220        except AttributeError:
1221          # For when raising error before name initialization.
1222          raise InvalidDefaultError('Invalid default value for %s: %r: %s' %
1223                                    (self.__class__.__name__, default, err))
1224        else:
1225          raise InvalidDefaultError('Invalid default value for field %s: '
1226                                    '%r: %s' % (name, default, err))
1227
1228    self.__default = default
1229    self.__initialized = True
1230
1231  def __setattr__(self, name, value):
1232    """Setter overidden to prevent assignment to fields after creation.
1233
1234    Args:
1235      name: Name of attribute to set.
1236      value: Value to assign.
1237    """
1238    # Special case post-init names.  They need to be set after constructor.
1239    if name in _POST_INIT_FIELD_ATTRIBUTE_NAMES:
1240      object.__setattr__(self, name, value)
1241      return
1242
1243    # All other attributes must be set before __initialized.
1244    if not self.__initialized:
1245      # Not initialized yet, allow assignment.
1246      object.__setattr__(self, name, value)
1247    else:
1248      raise AttributeError('Field objects are read-only')
1249
1250  def __set__(self, message_instance, value):
1251    """Set value on message.
1252
1253    Args:
1254      message_instance: Message instance to set value on.
1255      value: Value to set on message.
1256    """
1257    # Reaches in to message instance directly to assign to private tags.
1258    if value is None:
1259      if self.repeated:
1260        raise ValidationError(
1261          'May not assign None to repeated field %s' % self.name)
1262      else:
1263        message_instance._Message__tags.pop(self.number, None)
1264    else:
1265      if self.repeated:
1266        value = FieldList(self, value)
1267      else:
1268        self.validate(value)
1269      message_instance._Message__tags[self.number] = value
1270
1271  def __get__(self, message_instance, message_class):
1272    if message_instance is None:
1273      return self
1274
1275    result = message_instance._Message__tags.get(self.number)
1276    if result is None:
1277      return self.default
1278    else:
1279      return result
1280
1281  def validate_element(self, value):
1282    """Validate single element of field.
1283
1284    This is different from validate in that it is used on individual
1285    values of repeated fields.
1286
1287    Args:
1288      value: Value to validate.
1289
1290    Raises:
1291      ValidationError if value is not expected type.
1292    """
1293    if not isinstance(value, self.type):
1294      if value is None:
1295        if self.required:
1296          raise ValidationError('Required field is missing')
1297      else:
1298        try:
1299          name = self.name
1300        except AttributeError:
1301          raise ValidationError('Expected type %s for %s, '
1302                                'found %s (type %s)' %
1303                                (self.type, self.__class__.__name__,
1304                                 value, type(value)))
1305        else:
1306          raise ValidationError('Expected type %s for field %s, '
1307                                'found %s (type %s)' %
1308                                (self.type, name, value, type(value)))
1309
1310  def __validate(self, value, validate_element):
1311    """Internal validation function.
1312
1313    Validate an internal value using a function to validate individual elements.
1314
1315    Args:
1316      value: Value to validate.
1317      validate_element: Function to use to validate individual elements.
1318
1319    Raises:
1320      ValidationError if value is not expected type.
1321    """
1322    if not self.repeated:
1323      validate_element(value)
1324    else:
1325      # Must be a list or tuple, may not be a string.
1326      if isinstance(value, (list, tuple)):
1327        for element in value:
1328          if element is None:
1329            try:
1330              name = self.name
1331            except AttributeError:
1332              raise ValidationError('Repeated values for %s '
1333                                    'may not be None' % self.__class__.__name__)
1334            else:
1335              raise ValidationError('Repeated values for field %s '
1336                                    'may not be None' % name)
1337          validate_element(element)
1338      elif value is not None:
1339        try:
1340          name = self.name
1341        except AttributeError:
1342          raise ValidationError('%s is repeated. Found: %s' % (
1343            self.__class__.__name__, value))
1344        else:
1345          raise ValidationError('Field %s is repeated. Found: %s' % (name,
1346                                                                     value))
1347
1348  def validate(self, value):
1349    """Validate value assigned to field.
1350
1351    Args:
1352      value: Value to validate.
1353
1354    Raises:
1355      ValidationError if value is not expected type.
1356    """
1357    self.__validate(value, self.validate_element)
1358
1359  def validate_default_element(self, value):
1360    """Validate value as assigned to field default field.
1361
1362    Some fields may allow for delayed resolution of default types necessary
1363    in the case of circular definition references.  In this case, the default
1364    value might be a place holder that is resolved when needed after all the
1365    message classes are defined.
1366
1367    Args:
1368      value: Default value to validate.
1369
1370    Raises:
1371      ValidationError if value is not expected type.
1372    """
1373    self.validate_element(value)
1374
1375  def validate_default(self, value):
1376    """Validate default value assigned to field.
1377
1378    Args:
1379      value: Value to validate.
1380
1381    Raises:
1382      ValidationError if value is not expected type.
1383    """
1384    self.__validate(value, self.validate_default_element)
1385
1386  def message_definition(self):
1387    """Get Message definition that contains this Field definition.
1388
1389    Returns:
1390      Containing Message definition for Field.  Will return None if for
1391      some reason Field is defined outside of a Message class.
1392    """
1393    try:
1394      return self._message_definition()
1395    except AttributeError:
1396      return None
1397
1398  @property
1399  def default(self):
1400    """Get default value for field."""
1401    return self.__default
1402
1403  @classmethod
1404  def lookup_field_type_by_variant(cls, variant):
1405    return cls.__variant_to_type[variant]
1406
1407
1408class IntegerField(Field):
1409  """Field definition for integer values."""
1410
1411  VARIANTS = frozenset([Variant.INT32,
1412                        Variant.INT64,
1413                        Variant.UINT32,
1414                        Variant.UINT64,
1415                        Variant.SINT32,
1416                        Variant.SINT64,
1417                       ])
1418
1419  DEFAULT_VARIANT = Variant.INT64
1420
1421  type = six.integer_types
1422
1423
1424class FloatField(Field):
1425  """Field definition for float values."""
1426
1427  VARIANTS = frozenset([Variant.FLOAT,
1428                        Variant.DOUBLE,
1429                       ])
1430
1431  DEFAULT_VARIANT = Variant.DOUBLE
1432
1433  type = float
1434
1435
1436class BooleanField(Field):
1437  """Field definition for boolean values."""
1438
1439  VARIANTS = frozenset([Variant.BOOL])
1440
1441  DEFAULT_VARIANT = Variant.BOOL
1442
1443  type = bool
1444
1445
1446class BytesField(Field):
1447  """Field definition for byte string values."""
1448
1449  VARIANTS = frozenset([Variant.BYTES])
1450
1451  DEFAULT_VARIANT = Variant.BYTES
1452
1453  type = bytes
1454
1455
1456class StringField(Field):
1457  """Field definition for unicode string values."""
1458
1459  VARIANTS = frozenset([Variant.STRING])
1460
1461  DEFAULT_VARIANT = Variant.STRING
1462
1463  type = six.text_type
1464
1465  def validate_element(self, value):
1466    """Validate StringField allowing for str and unicode.
1467
1468    Raises:
1469      ValidationError if a str value is not 7-bit ascii.
1470    """
1471    # If value is str is it considered valid.  Satisfies "required=True".
1472    if isinstance(value, bytes):
1473      try:
1474        six.text_type(value, 'ascii')
1475      except UnicodeDecodeError as err:
1476        try:
1477          name = self.name
1478        except AttributeError:
1479          validation_error = ValidationError(
1480            'Field encountered non-ASCII string %r: %s' % (value,
1481                                                           err))
1482        else:
1483          validation_error = ValidationError(
1484            'Field %s encountered non-ASCII string %r: %s' % (self.name,
1485                                                              value,
1486                                                              err))
1487          validation_error.field_name = self.name
1488        raise validation_error
1489    else:
1490      super(StringField, self).validate_element(value)
1491
1492
1493class MessageField(Field):
1494  """Field definition for sub-message values.
1495
1496  Message fields contain instance of other messages.  Instances stored
1497  on messages stored on message fields  are considered to be owned by
1498  the containing message instance and should not be shared between
1499  owning instances.
1500
1501  Message fields must be defined to reference a single type of message.
1502  Normally message field are defined by passing the referenced message
1503  class in to the constructor.
1504
1505  It is possible to define a message field for a type that does not yet
1506  exist by passing the name of the message in to the constructor instead
1507  of a message class.  Resolution of the actual type of the message is
1508  deferred until it is needed, for example, during message verification.
1509  Names provided to the constructor must refer to a class within the same
1510  python module as the class that is using it.  Names refer to messages
1511  relative to the containing messages scope.  For example, the two fields
1512  of OuterMessage refer to the same message type:
1513
1514    class Outer(Message):
1515
1516      inner_relative = MessageField('Inner', 1)
1517      inner_absolute = MessageField('Outer.Inner', 2)
1518
1519      class Inner(Message):
1520        ...
1521
1522  When resolving an actual type, MessageField will traverse the entire
1523  scope of nested messages to match a message name.  This makes it easy
1524  for siblings to reference siblings:
1525
1526    class Outer(Message):
1527
1528      class Inner(Message):
1529
1530        sibling = MessageField('Sibling', 1)
1531
1532      class Sibling(Message):
1533        ...
1534  """
1535
1536  VARIANTS = frozenset([Variant.MESSAGE])
1537
1538  DEFAULT_VARIANT = Variant.MESSAGE
1539
1540  @util.positional(3)
1541  def __init__(self,
1542               message_type,
1543               number,
1544               required=False,
1545               repeated=False,
1546               variant=None):
1547    """Constructor.
1548
1549    Args:
1550      message_type: Message type for field.  Must be subclass of Message.
1551      number: Number of field.  Must be unique per message class.
1552      required: Whether or not field is required.  Mutually exclusive to
1553        'repeated'.
1554      repeated: Whether or not field is repeated.  Mutually exclusive to
1555        'required'.
1556      variant: Wire-format variant hint.
1557
1558    Raises:
1559      FieldDefinitionError when invalid message_type is provided.
1560    """
1561    valid_type = (isinstance(message_type, six.string_types) or
1562                  (message_type is not Message and
1563                   isinstance(message_type, type) and
1564                   issubclass(message_type, Message)))
1565
1566    if not valid_type:
1567      raise FieldDefinitionError('Invalid message class: %s' % message_type)
1568
1569    if isinstance(message_type, six.string_types):
1570      self.__type_name = message_type
1571      self.__type = None
1572    else:
1573      self.__type = message_type
1574
1575    super(MessageField, self).__init__(number,
1576                                       required=required,
1577                                       repeated=repeated,
1578                                       variant=variant)
1579
1580  def __set__(self, message_instance, value):
1581    """Set value on message.
1582
1583    Args:
1584      message_instance: Message instance to set value on.
1585      value: Value to set on message.
1586    """
1587    message_type = self.type
1588    if isinstance(message_type, type) and issubclass(message_type, Message):
1589      if self.repeated:
1590        if value and isinstance(value, (list, tuple)):
1591          value = [(message_type(**v) if isinstance(v, dict) else v)
1592                   for v in value]
1593      elif isinstance(value, dict):
1594        value = message_type(**value)
1595    super(MessageField, self).__set__(message_instance, value)
1596
1597  @property
1598  def type(self):
1599    """Message type used for field."""
1600    if self.__type is None:
1601      message_type = find_definition(self.__type_name, self.message_definition())
1602      if not (message_type is not Message and
1603              isinstance(message_type, type) and
1604              issubclass(message_type, Message)):
1605        raise FieldDefinitionError('Invalid message class: %s' % message_type)
1606      self.__type = message_type
1607    return self.__type
1608
1609  @property
1610  def message_type(self):
1611    """Underlying message type used for serialization.
1612
1613    Will always be a sub-class of Message.  This is different from type
1614    which represents the python value that message_type is mapped to for
1615    use by the user.
1616    """
1617    return self.type
1618
1619  def value_from_message(self, message):
1620    """Convert a message to a value instance.
1621
1622    Used by deserializers to convert from underlying messages to
1623    value of expected user type.
1624
1625    Args:
1626      message: A message instance of type self.message_type.
1627
1628    Returns:
1629      Value of self.message_type.
1630    """
1631    if not isinstance(message, self.message_type):
1632      raise DecodeError('Expected type %s, got %s: %r' %
1633                        (self.message_type.__name__,
1634                         type(message).__name__,
1635                         message))
1636    return message
1637
1638  def value_to_message(self, value):
1639    """Convert a value instance to a message.
1640
1641    Used by serializers to convert Python user types to underlying
1642    messages for transmission.
1643
1644    Args:
1645      value: A value of type self.type.
1646
1647    Returns:
1648      An instance of type self.message_type.
1649    """
1650    if not isinstance(value, self.type):
1651      raise EncodeError('Expected type %s, got %s: %r' %
1652                        (self.type.__name__,
1653                         type(value).__name__,
1654                         value))
1655    return value
1656
1657
1658class EnumField(Field):
1659  """Field definition for enum values.
1660
1661  Enum fields may have default values that are delayed until the associated enum
1662  type is resolved.  This is necessary to support certain circular references.
1663
1664  For example:
1665
1666    class Message1(Message):
1667
1668      class Color(Enum):
1669
1670        RED = 1
1671        GREEN = 2
1672        BLUE = 3
1673
1674      # This field default value  will be validated when default is accessed.
1675      animal = EnumField('Message2.Animal', 1, default='HORSE')
1676
1677    class Message2(Message):
1678
1679      class Animal(Enum):
1680
1681        DOG = 1
1682        CAT = 2
1683        HORSE = 3
1684
1685      # This fields default value will be validated right away since Color is
1686      # already fully resolved.
1687      color = EnumField(Message1.Color, 1, default='RED')
1688  """
1689
1690  VARIANTS = frozenset([Variant.ENUM])
1691
1692  DEFAULT_VARIANT = Variant.ENUM
1693
1694  def __init__(self, enum_type, number, **kwargs):
1695    """Constructor.
1696
1697    Args:
1698      enum_type: Enum type for field.  Must be subclass of Enum.
1699      number: Number of field.  Must be unique per message class.
1700      required: Whether or not field is required.  Mutually exclusive to
1701        'repeated'.
1702      repeated: Whether or not field is repeated.  Mutually exclusive to
1703        'required'.
1704      variant: Wire-format variant hint.
1705      default: Default value for field if not found in stream.
1706
1707    Raises:
1708      FieldDefinitionError when invalid enum_type is provided.
1709    """
1710    valid_type = (isinstance(enum_type, six.string_types) or
1711                  (enum_type is not Enum and
1712                   isinstance(enum_type, type) and
1713                   issubclass(enum_type, Enum)))
1714
1715    if not valid_type:
1716      raise FieldDefinitionError('Invalid enum type: %s' % enum_type)
1717
1718    if isinstance(enum_type, six.string_types):
1719      self.__type_name = enum_type
1720      self.__type = None
1721    else:
1722      self.__type = enum_type
1723
1724    super(EnumField, self).__init__(number, **kwargs)
1725
1726  def validate_default_element(self, value):
1727    """Validate default element of Enum field.
1728
1729    Enum fields allow for delayed resolution of default values when the type
1730    of the field has not been resolved.  The default value of a field may be
1731    a string or an integer.  If the Enum type of the field has been resolved,
1732    the default value is validated against that type.
1733
1734    Args:
1735      value: Value to validate.
1736
1737    Raises:
1738      ValidationError if value is not expected message type.
1739    """
1740    if isinstance(value, (six.string_types, six.integer_types)):
1741      # Validation of the value does not happen for delayed resolution
1742      # enumerated types.  Ignore if type is not yet resolved.
1743      if self.__type:
1744        self.__type(value)
1745      return
1746
1747    super(EnumField, self).validate_default_element(value)
1748
1749  @property
1750  def type(self):
1751    """Enum type used for field."""
1752    if self.__type is None:
1753      found_type = find_definition(self.__type_name, self.message_definition())
1754      if not (found_type is not Enum and
1755              isinstance(found_type, type) and
1756              issubclass(found_type, Enum)):
1757        raise FieldDefinitionError('Invalid enum type: %s' % found_type)
1758
1759      self.__type = found_type
1760    return self.__type
1761
1762  @property
1763  def default(self):
1764    """Default for enum field.
1765
1766    Will cause resolution of Enum type and unresolved default value.
1767    """
1768    try:
1769      return self.__resolved_default
1770    except AttributeError:
1771      resolved_default = super(EnumField, self).default
1772      if isinstance(resolved_default, (six.string_types, six.integer_types)):
1773        resolved_default = self.type(resolved_default)
1774      self.__resolved_default = resolved_default
1775      return self.__resolved_default
1776
1777
1778@util.positional(2)
1779def find_definition(name, relative_to=None, importer=__import__):
1780  """Find definition by name in module-space.
1781
1782  The find algorthm will look for definitions by name relative to a message
1783  definition or by fully qualfied name.  If no definition is found relative
1784  to the relative_to parameter it will do the same search against the container
1785  of relative_to.  If relative_to is a nested Message, it will search its
1786  message_definition().  If that message has no message_definition() it will
1787  search its module.  If relative_to is a module, it will attempt to look for
1788  the containing module and search relative to it.  If the module is a top-level
1789  module, it will look for the a message using a fully qualified name.  If
1790  no message is found then, the search fails and DefinitionNotFoundError is
1791  raised.
1792
1793  For example, when looking for any definition 'foo.bar.ADefinition' relative to
1794  an actual message definition abc.xyz.SomeMessage:
1795
1796    find_definition('foo.bar.ADefinition', SomeMessage)
1797
1798  It is like looking for the following fully qualified names:
1799
1800    abc.xyz.SomeMessage. foo.bar.ADefinition
1801    abc.xyz. foo.bar.ADefinition
1802    abc. foo.bar.ADefinition
1803    foo.bar.ADefinition
1804
1805  When resolving the name relative to Message definitions and modules, the
1806  algorithm searches any Messages or sub-modules found in its path.
1807  Non-Message values are not searched.
1808
1809  A name that begins with '.' is considered to be a fully qualified name.  The
1810  name is always searched for from the topmost package.  For example, assume
1811  two message types:
1812
1813    abc.xyz.SomeMessage
1814    xyz.SomeMessage
1815
1816  Searching for '.xyz.SomeMessage' relative to 'abc' will resolve to
1817  'xyz.SomeMessage' and not 'abc.xyz.SomeMessage'.  For this kind of name,
1818  the relative_to parameter is effectively ignored and always set to None.
1819
1820  For more information about package name resolution, please see:
1821
1822    http://code.google.com/apis/protocolbuffers/docs/proto.html#packages
1823
1824  Args:
1825    name: Name of definition to find.  May be fully qualified or relative name.
1826    relative_to: Search for definition relative to message definition or module.
1827      None will cause a fully qualified name search.
1828    importer: Import function to use for resolving modules.
1829
1830  Returns:
1831    Enum or Message class definition associated with name.
1832
1833  Raises:
1834    DefinitionNotFoundError if no definition is found in any search path.
1835  """
1836  # Check parameters.
1837  if not (relative_to is None or
1838          isinstance(relative_to, types.ModuleType) or
1839          isinstance(relative_to, type) and issubclass(relative_to, Message)):
1840    raise TypeError('relative_to must be None, Message definition or module.  '
1841                    'Found: %s' % relative_to)
1842
1843  name_path = name.split('.')
1844
1845  # Handle absolute path reference.
1846  if not name_path[0]:
1847    relative_to = None
1848    name_path = name_path[1:]
1849
1850  def search_path():
1851    """Performs a single iteration searching the path from relative_to.
1852
1853    This is the function that searches up the path from a relative object.
1854
1855      fully.qualified.object . relative.or.nested.Definition
1856                               ---------------------------->
1857                                                  ^
1858                                                  |
1859                            this part of search --+
1860
1861    Returns:
1862      Message or Enum at the end of name_path, else None.
1863    """
1864    next = relative_to
1865    for node in name_path:
1866      # Look for attribute first.
1867      attribute = getattr(next, node, None)
1868
1869      if attribute is not None:
1870        next = attribute
1871      else:
1872        # If module, look for sub-module.
1873        if next is None or isinstance(next, types.ModuleType):
1874          if next is None:
1875            module_name = node
1876          else:
1877            module_name = '%s.%s' % (next.__name__, node)
1878
1879          try:
1880            fromitem = module_name.split('.')[-1]
1881            next = importer(module_name, '', '', [str(fromitem)])
1882          except ImportError:
1883            return None
1884        else:
1885          return None
1886
1887      if (not isinstance(next, types.ModuleType) and
1888          not (isinstance(next, type) and
1889               issubclass(next, (Message, Enum)))):
1890        return None
1891
1892    return next
1893
1894  while True:
1895    found = search_path()
1896    if isinstance(found, type) and issubclass(found, (Enum, Message)):
1897      return found
1898    else:
1899      # Find next relative_to to search against.
1900      #
1901      #   fully.qualified.object . relative.or.nested.Definition
1902      #   <---------------------
1903      #           ^
1904      #           |
1905      #   does this part of search
1906      if relative_to is None:
1907        # Fully qualified search was done.  Nothing found.  Fail.
1908        raise DefinitionNotFoundError('Could not find definition for %s'
1909                                      % (name,))
1910      else:
1911        if isinstance(relative_to, types.ModuleType):
1912          # Find parent module.
1913          module_path = relative_to.__name__.split('.')[:-1]
1914          if not module_path:
1915            relative_to = None
1916          else:
1917            # Should not raise ImportError.  If it does... weird and
1918            # unexepected.  Propagate.
1919            relative_to = importer(
1920              '.'.join(module_path), '', '', [module_path[-1]])
1921        elif (isinstance(relative_to, type) and
1922              issubclass(relative_to, Message)):
1923          parent = relative_to.message_definition()
1924          if parent is None:
1925            last_module_name = relative_to.__module__.split('.')[-1]
1926            relative_to = importer(
1927              relative_to.__module__, '', '', [last_module_name])
1928          else:
1929            relative_to = parent
1930