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