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