• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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    # TODO(craigcitro): Remove this alias.
1172    #
1173    # We add an alias here for backwards compatibility; note that in
1174    # python3, this attribute will silently be ignored.
1175    __metaclass__ = _FieldMeta
1176
1177    @util.positional(2)
1178    def __init__(self,
1179                 number,
1180                 required=False,
1181                 repeated=False,
1182                 variant=None,
1183                 default=None):
1184        """Constructor.
1185
1186        The required and repeated parameters are mutually exclusive.
1187        Setting both to True will raise a FieldDefinitionError.
1188
1189        Sub-class Attributes:
1190          Each sub-class of Field must define the following:
1191            VARIANTS: Set of variant types accepted by that field.
1192            DEFAULT_VARIANT: Default variant type if not specified in
1193              constructor.
1194
1195        Args:
1196          number: Number of field.  Must be unique per message class.
1197          required: Whether or not field is required.  Mutually exclusive with
1198            'repeated'.
1199          repeated: Whether or not field is repeated.  Mutually exclusive with
1200            'required'.
1201          variant: Wire-format variant hint.
1202          default: Default value for field if not found in stream.
1203
1204        Raises:
1205          InvalidVariantError when invalid variant for field is provided.
1206          InvalidDefaultError when invalid default for field is provided.
1207          FieldDefinitionError when invalid number provided or mutually
1208            exclusive fields are used.
1209          InvalidNumberError when the field number is out of range or reserved.
1210
1211        """
1212        if not isinstance(number, int) or not 1 <= number <= MAX_FIELD_NUMBER:
1213            raise InvalidNumberError(
1214                'Invalid number for field: %s\n'
1215                'Number must be 1 or greater and %d or less' %
1216                (number, MAX_FIELD_NUMBER))
1217
1218        if FIRST_RESERVED_FIELD_NUMBER <= number <= LAST_RESERVED_FIELD_NUMBER:
1219            raise InvalidNumberError('Tag number %d is a reserved number.\n'
1220                                     'Numbers %d to %d are reserved' %
1221                                     (number, FIRST_RESERVED_FIELD_NUMBER,
1222                                      LAST_RESERVED_FIELD_NUMBER))
1223
1224        if repeated and required:
1225            raise FieldDefinitionError('Cannot set both repeated and required')
1226
1227        if variant is None:
1228            variant = self.DEFAULT_VARIANT
1229
1230        if repeated and default is not None:
1231            raise FieldDefinitionError('Repeated fields may not have defaults')
1232
1233        if variant not in self.VARIANTS:
1234            raise InvalidVariantError(
1235                'Invalid variant: %s\nValid variants for %s are %r' %
1236                (variant, type(self).__name__, sorted(self.VARIANTS)))
1237
1238        self.number = number
1239        self.required = required
1240        self.repeated = repeated
1241        self.variant = variant
1242
1243        if default is not None:
1244            try:
1245                self.validate_default(default)
1246            except ValidationError as err:
1247                try:
1248                    name = self.name
1249                except AttributeError:
1250                    # For when raising error before name initialization.
1251                    raise InvalidDefaultError(
1252                        'Invalid default value for %s: %r: %s' %
1253                        (self.__class__.__name__, default, err))
1254                else:
1255                    raise InvalidDefaultError(
1256                        'Invalid default value for field %s: '
1257                        '%r: %s' % (name, default, err))
1258
1259        self.__default = default
1260        self.__initialized = True
1261
1262    def __setattr__(self, name, value):
1263        """Setter overidden to prevent assignment to fields after creation.
1264
1265        Args:
1266          name: Name of attribute to set.
1267          value: Value to assign.
1268        """
1269        # Special case post-init names.  They need to be set after constructor.
1270        if name in _POST_INIT_FIELD_ATTRIBUTE_NAMES:
1271            object.__setattr__(self, name, value)
1272            return
1273
1274        # All other attributes must be set before __initialized.
1275        if not self.__initialized:
1276            # Not initialized yet, allow assignment.
1277            object.__setattr__(self, name, value)
1278        else:
1279            raise AttributeError('Field objects are read-only')
1280
1281    def __set__(self, message_instance, value):
1282        """Set value on message.
1283
1284        Args:
1285          message_instance: Message instance to set value on.
1286          value: Value to set on message.
1287        """
1288        # Reaches in to message instance directly to assign to private tags.
1289        if value is None:
1290            if self.repeated:
1291                raise ValidationError(
1292                    'May not assign None to repeated field %s' % self.name)
1293            else:
1294                message_instance._Message__tags.pop(self.number, None)
1295        else:
1296            if self.repeated:
1297                value = FieldList(self, value)
1298            else:
1299                value = self.validate(value)
1300            message_instance._Message__tags[self.number] = value
1301
1302    def __get__(self, message_instance, message_class):
1303        if message_instance is None:
1304            return self
1305
1306        result = message_instance._Message__tags.get(self.number)
1307        if result is None:
1308            return self.default
1309        return result
1310
1311    def validate_element(self, value):
1312        """Validate single element of field.
1313
1314        This is different from validate in that it is used on individual
1315        values of repeated fields.
1316
1317        Args:
1318          value: Value to validate.
1319
1320        Returns:
1321          The value casted in the expected type.
1322
1323        Raises:
1324          ValidationError if value is not expected type.
1325        """
1326        if not isinstance(value, self.type):
1327
1328            # Authorize int values as float.
1329            if isinstance(value, six.integer_types) and self.type == float:
1330                return float(value)
1331
1332            if value is None:
1333                if self.required:
1334                    raise ValidationError('Required field is missing')
1335            else:
1336                try:
1337                    name = self.name
1338                except AttributeError:
1339                    raise ValidationError('Expected type %s for %s, '
1340                                          'found %s (type %s)' %
1341                                          (self.type, self.__class__.__name__,
1342                                           value, type(value)))
1343                else:
1344                    raise ValidationError(
1345                        'Expected type %s for field %s, found %s (type %s)' %
1346                        (self.type, name, value, type(value)))
1347        return value
1348
1349    def __validate(self, value, validate_element):
1350        """Internal validation function.
1351
1352        Validate an internal value using a function to validate
1353        individual elements.
1354
1355        Args:
1356          value: Value to validate.
1357          validate_element: Function to use to validate individual elements.
1358
1359        Raises:
1360          ValidationError if value is not expected type.
1361
1362        """
1363        if not self.repeated:
1364            return validate_element(value)
1365        else:
1366            # Must be a list or tuple, may not be a string.
1367            if isinstance(value, (list, tuple)):
1368                result = []
1369                for element in value:
1370                    if element is None:
1371                        try:
1372                            name = self.name
1373                        except AttributeError:
1374                            raise ValidationError(
1375                                'Repeated values for %s '
1376                                'may not be None' % self.__class__.__name__)
1377                        else:
1378                            raise ValidationError(
1379                                'Repeated values for field %s '
1380                                'may not be None' % name)
1381                    result.append(validate_element(element))
1382                return result
1383            elif value is not None:
1384                try:
1385                    name = self.name
1386                except AttributeError:
1387                    raise ValidationError('%s is repeated. Found: %s' % (
1388                        self.__class__.__name__, value))
1389                else:
1390                    raise ValidationError(
1391                        'Field %s is repeated. Found: %s' % (name, value))
1392        return value
1393
1394    def validate(self, value):
1395        """Validate value assigned to field.
1396
1397        Args:
1398          value: Value to validate.
1399
1400        Returns:
1401          the value in casted in the correct type.
1402
1403        Raises:
1404          ValidationError if value is not expected type.
1405        """
1406        return self.__validate(value, self.validate_element)
1407
1408    def validate_default_element(self, value):
1409        """Validate value as assigned to field default field.
1410
1411        Some fields may allow for delayed resolution of default types
1412        necessary in the case of circular definition references. In
1413        this case, the default value might be a place holder that is
1414        resolved when needed after all the message classes are
1415        defined.
1416
1417        Args:
1418          value: Default value to validate.
1419
1420        Returns:
1421          the value in casted in the correct type.
1422
1423        Raises:
1424          ValidationError if value is not expected type.
1425
1426        """
1427        return self.validate_element(value)
1428
1429    def validate_default(self, value):
1430        """Validate default value assigned to field.
1431
1432        Args:
1433          value: Value to validate.
1434
1435        Returns:
1436          the value in casted in the correct type.
1437
1438        Raises:
1439          ValidationError if value is not expected type.
1440        """
1441        return self.__validate(value, self.validate_default_element)
1442
1443    def message_definition(self):
1444        """Get Message definition that contains this Field definition.
1445
1446        Returns:
1447          Containing Message definition for Field. Will return None if
1448          for some reason Field is defined outside of a Message class.
1449
1450        """
1451        try:
1452            return self._message_definition()
1453        except AttributeError:
1454            return None
1455
1456    @property
1457    def default(self):
1458        """Get default value for field."""
1459        return self.__default
1460
1461    @classmethod
1462    def lookup_field_type_by_variant(cls, variant):
1463        return cls.__variant_to_type[variant]
1464
1465
1466class IntegerField(Field):
1467    """Field definition for integer values."""
1468
1469    VARIANTS = frozenset([
1470        Variant.INT32,
1471        Variant.INT64,
1472        Variant.UINT32,
1473        Variant.UINT64,
1474        Variant.SINT32,
1475        Variant.SINT64,
1476    ])
1477
1478    DEFAULT_VARIANT = Variant.INT64
1479
1480    type = six.integer_types
1481
1482
1483class FloatField(Field):
1484    """Field definition for float values."""
1485
1486    VARIANTS = frozenset([
1487        Variant.FLOAT,
1488        Variant.DOUBLE,
1489    ])
1490
1491    DEFAULT_VARIANT = Variant.DOUBLE
1492
1493    type = float
1494
1495
1496class BooleanField(Field):
1497    """Field definition for boolean values."""
1498
1499    VARIANTS = frozenset([Variant.BOOL])
1500
1501    DEFAULT_VARIANT = Variant.BOOL
1502
1503    type = bool
1504
1505
1506class BytesField(Field):
1507    """Field definition for byte string values."""
1508
1509    VARIANTS = frozenset([Variant.BYTES])
1510
1511    DEFAULT_VARIANT = Variant.BYTES
1512
1513    type = bytes
1514
1515
1516class StringField(Field):
1517    """Field definition for unicode string values."""
1518
1519    VARIANTS = frozenset([Variant.STRING])
1520
1521    DEFAULT_VARIANT = Variant.STRING
1522
1523    type = six.text_type
1524
1525    def validate_element(self, value):
1526        """Validate StringField allowing for str and unicode.
1527
1528        Raises:
1529          ValidationError if a str value is not 7-bit ascii.
1530        """
1531        # If value is str is it considered valid.  Satisfies "required=True".
1532        if isinstance(value, bytes):
1533            try:
1534                six.text_type(value, 'ascii')
1535            except UnicodeDecodeError as err:
1536                try:
1537                    _ = self.name
1538                except AttributeError:
1539                    validation_error = ValidationError(
1540                        'Field encountered non-ASCII string %r: %s' % (value,
1541                                                                       err))
1542                else:
1543                    validation_error = ValidationError(
1544                        'Field %s encountered non-ASCII string %r: %s' % (
1545                            self.name, value, err))
1546                    validation_error.field_name = self.name
1547                raise validation_error
1548        else:
1549            return super(StringField, self).validate_element(value)
1550        return value
1551
1552
1553class MessageField(Field):
1554    """Field definition for sub-message values.
1555
1556    Message fields contain instance of other messages.  Instances stored
1557    on messages stored on message fields  are considered to be owned by
1558    the containing message instance and should not be shared between
1559    owning instances.
1560
1561    Message fields must be defined to reference a single type of message.
1562    Normally message field are defined by passing the referenced message
1563    class in to the constructor.
1564
1565    It is possible to define a message field for a type that does not
1566    yet exist by passing the name of the message in to the constructor
1567    instead of a message class. Resolution of the actual type of the
1568    message is deferred until it is needed, for example, during
1569    message verification. Names provided to the constructor must refer
1570    to a class within the same python module as the class that is
1571    using it. Names refer to messages relative to the containing
1572    messages scope. For example, the two fields of OuterMessage refer
1573    to the same message type:
1574
1575      class Outer(Message):
1576
1577        inner_relative = MessageField('Inner', 1)
1578        inner_absolute = MessageField('Outer.Inner', 2)
1579
1580        class Inner(Message):
1581          ...
1582
1583    When resolving an actual type, MessageField will traverse the
1584    entire scope of nested messages to match a message name. This
1585    makes it easy for siblings to reference siblings:
1586
1587      class Outer(Message):
1588
1589        class Inner(Message):
1590
1591          sibling = MessageField('Sibling', 1)
1592
1593        class Sibling(Message):
1594          ...
1595
1596    """
1597
1598    VARIANTS = frozenset([Variant.MESSAGE])
1599
1600    DEFAULT_VARIANT = Variant.MESSAGE
1601
1602    @util.positional(3)
1603    def __init__(self,
1604                 message_type,
1605                 number,
1606                 required=False,
1607                 repeated=False,
1608                 variant=None):
1609        """Constructor.
1610
1611        Args:
1612          message_type: Message type for field.  Must be subclass of Message.
1613          number: Number of field.  Must be unique per message class.
1614          required: Whether or not field is required.  Mutually exclusive to
1615            'repeated'.
1616          repeated: Whether or not field is repeated.  Mutually exclusive to
1617            'required'.
1618          variant: Wire-format variant hint.
1619
1620        Raises:
1621          FieldDefinitionError when invalid message_type is provided.
1622        """
1623        valid_type = (isinstance(message_type, six.string_types) or
1624                      (message_type is not Message and
1625                       isinstance(message_type, type) and
1626                       issubclass(message_type, Message)))
1627
1628        if not valid_type:
1629            raise FieldDefinitionError(
1630                'Invalid message class: %s' % message_type)
1631
1632        if isinstance(message_type, six.string_types):
1633            self.__type_name = message_type
1634            self.__type = None
1635        else:
1636            self.__type = message_type
1637
1638        super(MessageField, self).__init__(number,
1639                                           required=required,
1640                                           repeated=repeated,
1641                                           variant=variant)
1642
1643    def __set__(self, message_instance, value):
1644        """Set value on message.
1645
1646        Args:
1647          message_instance: Message instance to set value on.
1648          value: Value to set on message.
1649        """
1650        t = self.type
1651        if isinstance(t, type) and issubclass(t, Message):
1652            if self.repeated:
1653                if value and isinstance(value, (list, tuple)):
1654                    value = [(t(**v) if isinstance(v, dict) else v)
1655                             for v in value]
1656            elif isinstance(value, dict):
1657                value = t(**value)
1658        super(MessageField, self).__set__(message_instance, value)
1659
1660    @property
1661    def type(self):
1662        """Message type used for field."""
1663        if self.__type is None:
1664            message_type = find_definition(
1665                self.__type_name, self.message_definition())
1666            if not (message_type is not Message and
1667                    isinstance(message_type, type) and
1668                    issubclass(message_type, Message)):
1669                raise FieldDefinitionError(
1670                    'Invalid message class: %s' % message_type)
1671            self.__type = message_type
1672        return self.__type
1673
1674    @property
1675    def message_type(self):
1676        """Underlying message type used for serialization.
1677
1678        Will always be a sub-class of Message.  This is different from type
1679        which represents the python value that message_type is mapped to for
1680        use by the user.
1681        """
1682        return self.type
1683
1684    def value_from_message(self, message):
1685        """Convert a message to a value instance.
1686
1687        Used by deserializers to convert from underlying messages to
1688        value of expected user type.
1689
1690        Args:
1691          message: A message instance of type self.message_type.
1692
1693        Returns:
1694          Value of self.message_type.
1695        """
1696        if not isinstance(message, self.message_type):
1697            raise DecodeError('Expected type %s, got %s: %r' %
1698                              (self.message_type.__name__,
1699                               type(message).__name__,
1700                               message))
1701        return message
1702
1703    def value_to_message(self, value):
1704        """Convert a value instance to a message.
1705
1706        Used by serializers to convert Python user types to underlying
1707        messages for transmission.
1708
1709        Args:
1710          value: A value of type self.type.
1711
1712        Returns:
1713          An instance of type self.message_type.
1714        """
1715        if not isinstance(value, self.type):
1716            raise EncodeError('Expected type %s, got %s: %r' %
1717                              (self.type.__name__,
1718                               type(value).__name__,
1719                               value))
1720        return value
1721
1722
1723class EnumField(Field):
1724    """Field definition for enum values.
1725
1726    Enum fields may have default values that are delayed until the
1727    associated enum type is resolved. This is necessary to support
1728    certain circular references.
1729
1730    For example:
1731
1732      class Message1(Message):
1733
1734        class Color(Enum):
1735
1736          RED = 1
1737          GREEN = 2
1738          BLUE = 3
1739
1740        # This field default value  will be validated when default is accessed.
1741        animal = EnumField('Message2.Animal', 1, default='HORSE')
1742
1743      class Message2(Message):
1744
1745        class Animal(Enum):
1746
1747          DOG = 1
1748          CAT = 2
1749          HORSE = 3
1750
1751        # This fields default value will be validated right away since Color
1752        # is already fully resolved.
1753        color = EnumField(Message1.Color, 1, default='RED')
1754    """
1755
1756    VARIANTS = frozenset([Variant.ENUM])
1757
1758    DEFAULT_VARIANT = Variant.ENUM
1759
1760    def __init__(self, enum_type, number, **kwargs):
1761        """Constructor.
1762
1763        Args:
1764          enum_type: Enum type for field.  Must be subclass of Enum.
1765          number: Number of field.  Must be unique per message class.
1766          required: Whether or not field is required.  Mutually exclusive to
1767            'repeated'.
1768          repeated: Whether or not field is repeated.  Mutually exclusive to
1769            'required'.
1770          variant: Wire-format variant hint.
1771          default: Default value for field if not found in stream.
1772
1773        Raises:
1774          FieldDefinitionError when invalid enum_type is provided.
1775        """
1776        valid_type = (isinstance(enum_type, six.string_types) or
1777                      (enum_type is not Enum and
1778                       isinstance(enum_type, type) and
1779                       issubclass(enum_type, Enum)))
1780
1781        if not valid_type:
1782            raise FieldDefinitionError('Invalid enum type: %s' % enum_type)
1783
1784        if isinstance(enum_type, six.string_types):
1785            self.__type_name = enum_type
1786            self.__type = None
1787        else:
1788            self.__type = enum_type
1789
1790        super(EnumField, self).__init__(number, **kwargs)
1791
1792    def validate_default_element(self, value):
1793        """Validate default element of Enum field.
1794
1795        Enum fields allow for delayed resolution of default values
1796        when the type of the field has not been resolved. The default
1797        value of a field may be a string or an integer. If the Enum
1798        type of the field has been resolved, the default value is
1799        validated against that type.
1800
1801        Args:
1802          value: Value to validate.
1803
1804        Raises:
1805          ValidationError if value is not expected message type.
1806
1807        """
1808        if isinstance(value, (six.string_types, six.integer_types)):
1809            # Validation of the value does not happen for delayed resolution
1810            # enumerated types.  Ignore if type is not yet resolved.
1811            if self.__type:
1812                self.__type(value)
1813            return value
1814
1815        return super(EnumField, self).validate_default_element(value)
1816
1817    @property
1818    def type(self):
1819        """Enum type used for field."""
1820        if self.__type is None:
1821            found_type = find_definition(
1822                self.__type_name, self.message_definition())
1823            if not (found_type is not Enum and
1824                    isinstance(found_type, type) and
1825                    issubclass(found_type, Enum)):
1826                raise FieldDefinitionError(
1827                    'Invalid enum type: %s' % found_type)
1828
1829            self.__type = found_type
1830        return self.__type
1831
1832    @property
1833    def default(self):
1834        """Default for enum field.
1835
1836        Will cause resolution of Enum type and unresolved default value.
1837        """
1838        try:
1839            return self.__resolved_default
1840        except AttributeError:
1841            resolved_default = super(EnumField, self).default
1842            if isinstance(resolved_default, (six.string_types,
1843                                             six.integer_types)):
1844                # pylint:disable=not-callable
1845                resolved_default = self.type(resolved_default)
1846            self.__resolved_default = resolved_default
1847            return self.__resolved_default
1848
1849
1850@util.positional(2)
1851def find_definition(name, relative_to=None, importer=__import__):
1852    """Find definition by name in module-space.
1853
1854    The find algorthm will look for definitions by name relative to a
1855    message definition or by fully qualfied name. If no definition is
1856    found relative to the relative_to parameter it will do the same
1857    search against the container of relative_to. If relative_to is a
1858    nested Message, it will search its message_definition(). If that
1859    message has no message_definition() it will search its module. If
1860    relative_to is a module, it will attempt to look for the
1861    containing module and search relative to it. If the module is a
1862    top-level module, it will look for the a message using a fully
1863    qualified name. If no message is found then, the search fails and
1864    DefinitionNotFoundError is raised.
1865
1866    For example, when looking for any definition 'foo.bar.ADefinition'
1867    relative to an actual message definition abc.xyz.SomeMessage:
1868
1869      find_definition('foo.bar.ADefinition', SomeMessage)
1870
1871    It is like looking for the following fully qualified names:
1872
1873      abc.xyz.SomeMessage. foo.bar.ADefinition
1874      abc.xyz. foo.bar.ADefinition
1875      abc. foo.bar.ADefinition
1876      foo.bar.ADefinition
1877
1878    When resolving the name relative to Message definitions and modules, the
1879    algorithm searches any Messages or sub-modules found in its path.
1880    Non-Message values are not searched.
1881
1882    A name that begins with '.' is considered to be a fully qualified
1883    name. The name is always searched for from the topmost package.
1884    For example, assume two message types:
1885
1886      abc.xyz.SomeMessage
1887      xyz.SomeMessage
1888
1889    Searching for '.xyz.SomeMessage' relative to 'abc' will resolve to
1890    'xyz.SomeMessage' and not 'abc.xyz.SomeMessage'.  For this kind of name,
1891    the relative_to parameter is effectively ignored and always set to None.
1892
1893    For more information about package name resolution, please see:
1894
1895      http://code.google.com/apis/protocolbuffers/docs/proto.html#packages
1896
1897    Args:
1898      name: Name of definition to find.  May be fully qualified or relative
1899        name.
1900      relative_to: Search for definition relative to message definition or
1901        module. None will cause a fully qualified name search.
1902      importer: Import function to use for resolving modules.
1903
1904    Returns:
1905      Enum or Message class definition associated with name.
1906
1907    Raises:
1908      DefinitionNotFoundError if no definition is found in any search path.
1909
1910    """
1911    # Check parameters.
1912    if not (relative_to is None or
1913            isinstance(relative_to, types.ModuleType) or
1914            isinstance(relative_to, type) and
1915            issubclass(relative_to, Message)):
1916        raise TypeError(
1917            'relative_to must be None, Message definition or module.'
1918            '  Found: %s' % relative_to)
1919
1920    name_path = name.split('.')
1921
1922    # Handle absolute path reference.
1923    if not name_path[0]:
1924        relative_to = None
1925        name_path = name_path[1:]
1926
1927    def search_path():
1928        """Performs a single iteration searching the path from relative_to.
1929
1930        This is the function that searches up the path from a relative object.
1931
1932          fully.qualified.object . relative.or.nested.Definition
1933                                   ---------------------------->
1934                                                      ^
1935                                                      |
1936                                this part of search --+
1937
1938        Returns:
1939          Message or Enum at the end of name_path, else None.
1940        """
1941        next_part = relative_to
1942        for node in name_path:
1943            # Look for attribute first.
1944            attribute = getattr(next_part, node, None)
1945
1946            if attribute is not None:
1947                next_part = attribute
1948            else:
1949                # If module, look for sub-module.
1950                if (next_part is None or
1951                        isinstance(next_part, types.ModuleType)):
1952                    if next_part is None:
1953                        module_name = node
1954                    else:
1955                        module_name = '%s.%s' % (next_part.__name__, node)
1956
1957                    try:
1958                        fromitem = module_name.split('.')[-1]
1959                        next_part = importer(module_name, '', '',
1960                                             [str(fromitem)])
1961                    except ImportError:
1962                        return None
1963                else:
1964                    return None
1965
1966            if not isinstance(next_part, types.ModuleType):
1967                if not (isinstance(next_part, type) and
1968                        issubclass(next_part, (Message, Enum))):
1969                    return None
1970
1971        return next_part
1972
1973    while True:
1974        found = search_path()
1975        if isinstance(found, type) and issubclass(found, (Enum, Message)):
1976            return found
1977        else:
1978            # Find next relative_to to search against.
1979            #
1980            #   fully.qualified.object . relative.or.nested.Definition
1981            #   <---------------------
1982            #           ^
1983            #           |
1984            #   does this part of search
1985            if relative_to is None:
1986                # Fully qualified search was done.  Nothing found.  Fail.
1987                raise DefinitionNotFoundError(
1988                    'Could not find definition for %s' % name)
1989            else:
1990                if isinstance(relative_to, types.ModuleType):
1991                    # Find parent module.
1992                    module_path = relative_to.__name__.split('.')[:-1]
1993                    if not module_path:
1994                        relative_to = None
1995                    else:
1996                        # Should not raise ImportError. If it does...
1997                        # weird and unexpected. Propagate.
1998                        relative_to = importer(
1999                            '.'.join(module_path), '', '', [module_path[-1]])
2000                elif (isinstance(relative_to, type) and
2001                      issubclass(relative_to, Message)):
2002                    parent = relative_to.message_definition()
2003                    if parent is None:
2004                        last_module_name = relative_to.__module__.split(
2005                            '.')[-1]
2006                        relative_to = importer(
2007                            relative_to.__module__, '', '', [last_module_name])
2008                    else:
2009                        relative_to = parent
2010