#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#




"""Validation tools for generic object structures.

This library is used for defining classes with constrained attributes.
Attributes are defined on the class which contains them using validators.
Although validators can be defined by any client of this library, a number
of standard validators are provided here.

Validators can be any callable that takes a single parameter which checks
the new value before it is assigned to the attribute.  Validators are
permitted to modify a received value so that it is appropriate for the
attribute definition.  For example, using int as a validator will cast
a correctly formatted string to a number, or raise an exception if it
can not.  This is not recommended, however.  the correct way to use a
validator that ensure the correct type is to use the Type validator.

This validation library is mainly intended for use with the YAML object
builder.  See yaml_object.py.
"""









import re

import google
import yaml


class Error(Exception):
  """Base class for all package errors."""


class AttributeDefinitionError(Error):
  """An error occurred in the definition of class attributes."""


class ValidationError(Error):
  """Base class for raising exceptions during validation."""

  def __init__(self, message, cause=None):
    """Initialize exception."""
    if hasattr(cause, 'args') and cause.args:
      Error.__init__(self, message, *cause.args)
    else:


      Error.__init__(self, message)
    self.message = message
    self.cause = cause

  def __str__(self):
    return str(self.message)


class MissingAttribute(ValidationError):
  """Raised when a required attribute is missing from object."""


def AsValidator(validator):
  """Wrap various types as instances of a validator.

  Used to allow shorthand for common validator types.  It
  converts the following types to the following Validators.

    strings -> Regex
    type -> Type
    collection -> Options
    Validator -> Its self!

  Args:
    validator: Object to wrap in a validator.

  Returns:
    Validator instance that wraps the given value.

  Raises:
    AttributeDefinitionError: if validator is not one of the above described
      types.
  """
  if isinstance(validator, (str, unicode)):
    return Regex(validator, type(validator))
  if isinstance(validator, type):
    return Type(validator)
  if isinstance(validator, (list, tuple, set)):
    return Options(*tuple(validator))
  if isinstance(validator, Validator):
    return validator
  else:
    raise AttributeDefinitionError('%s is not a valid validator' %
                                   str(validator))


def _SimplifiedValue(validator, value):
  """Convert any value to simplified collections and basic types.

  Args:
    validator: An instance of Validator that corresponds with 'value'.
      May also be 'str' or 'int' if those were used instead of a full
      Validator.
    value: Value to convert to simplified collections.

  Returns:
    The value as a dictionary if it is a ValidatedBase object.  A list of
    items converted to simplified collections if value is a list
    or a tuple. Otherwise, just the value.
  """
  if isinstance(value, ValidatedBase):

    return value.ToDict()
  elif isinstance(value, (list, tuple)):

    return [_SimplifiedValue(validator, item) for item in value]
  elif isinstance(validator, Validator):
    return validator.ToValue(value)
  return value


class ValidatedBase(object):
  """Base class for all validated objects."""

  @classmethod
  def GetValidator(self, key):
    """Safely get the Validator corresponding to the given key.

    This function should be overridden by subclasses

    Args:
      key: The attribute or item to get a validator for.

    Returns:
      Validator associated with key or attribute.

    Raises:
      ValidationError: if the requested key is illegal.
    """
    raise NotImplementedError('Subclasses of ValidatedBase must '
                              'override GetValidator.')

  def SetMultiple(self, attributes):
    """Set multiple values on Validated instance.

    All attributes will be validated before being set.

    Args:
      attributes: A dict of attributes/items to set.

    Raises:
      ValidationError: when no validated attribute exists on class.
    """
    for key, value in attributes.iteritems():
      self.Set(key, value)

  def Set(self, key, value):
    """Set a single value on Validated instance.

    This method should be overridded by sub-classes.

    This method can only be used to assign validated attributes/items.

    Args:
      key: The name of the attributes
      value: The value to set

    Raises:
      ValidationError: when no validated attribute exists on class.
    """
    raise NotImplementedError('Subclasses of ValidatedBase must override Set.')

  def CheckInitialized(self):
    """Checks that all required fields are initialized.

    This function is called after all attributes have been checked to
    verify any higher level constraints, for example ensuring all required
    attributes are present.

    Subclasses should override this function and raise an exception for
    any errors.
    """
    pass

  def ToDict(self):
    """Convert ValidatedBase object to a dictionary.

    Recursively traverses all of its elements and converts everything to
    simplified collections.

    Subclasses should override this method.

    Returns:
      A dictionary mapping all attributes to simple values or collections.
    """
    raise NotImplementedError('Subclasses of ValidatedBase must '
                              'override ToDict.')

  def ToYAML(self):
    """Print validated object as simplified YAML.

    Returns:
      Object as a simplified YAML string compatible with parsing using the
      SafeLoader.
    """
    return yaml.dump(self.ToDict(),
                     default_flow_style=False,
                     Dumper=yaml.SafeDumper)


class Validated(ValidatedBase):
  """Base class for classes that require validation.

  A class which intends to use validated fields should sub-class itself from
  this class.  Each class should define an 'ATTRIBUTES' class variable which
  should be a map from attribute name to its validator.  For example:

    class Story(Validated):
      ATTRIBUTES = {'title': Type(str),
                    'authors': Repeated(Type(str)),
                    'isbn': Optional(Type(str)),
                    'pages': Type(int),
                    }

  Attributes that are not listed under ATTRIBUTES work like normal and are
  not validated upon assignment.
  """


  ATTRIBUTES = None

  def __init__(self, **attributes):
    """Constructor for Validated classes.

    This constructor can optionally assign values to the class via its
    keyword arguments.

    Raises:
      AttributeDefinitionError: when class instance is missing ATTRIBUTE
        definition or when ATTRIBUTE is of the wrong type.
    """
    if not isinstance(self.ATTRIBUTES, dict):
      raise AttributeDefinitionError(
          'The class %s does not define an ATTRIBUTE variable.'
          % self.__class__)


    for key in self.ATTRIBUTES.keys():
      object.__setattr__(self, key, self.GetValidator(key).default)

    self.SetMultiple(attributes)

  @classmethod
  def GetValidator(self, key):
    """Safely get the underlying attribute definition as a Validator.

    Args:
      key: Name of attribute to get.

    Returns:
      Validator associated with key or attribute value wrapped in a
      validator.
    """
    if key not in self.ATTRIBUTES:
      raise ValidationError(
          'Unexpected attribute \'%s\' for object of type %s.' %
          (key, self.__name__))

    return AsValidator(self.ATTRIBUTES[key])

  def Set(self, key, value):
    """Set a single value on Validated instance.

    This method can only be used to assign validated attributes.

    Args:
      key: The name of the attributes
      value: The value to set

    Raises:
      ValidationError when no validated attribute exists on class.
    """
    setattr(self, key, value)

  def Get(self, key):
    """Get a single value on Validated instance.

    This method can only be used to retrieve validated attributes.

    Args:
      key: The name of the attributes

    Raises:
      ValidationError when no validated attribute exists on class.
    """
    self.GetValidator(key)
    return getattr(self, key)

  def CheckInitialized(self):
    """Checks that all required fields are initialized.

    Since an instance of Validated starts off in an uninitialized state, it
    is sometimes necessary to check that it has been fully initialized.
    The main problem this solves is how to validate that an instance has
    all of its required fields set.  By default, Validator classes do not
    allow None, but all attributes are initialized to None when instantiated.

    Raises:
      Exception relevant to the kind of validation.  The type of the exception
      is determined by the validator.  Typically this will be ValueError or
      TypeError.
    """
    for key in self.ATTRIBUTES.iterkeys():
      try:
        self.GetValidator(key)(getattr(self, key))
      except MissingAttribute, e:
        e.message = "Missing required value '%s'." % key
        raise e

  def __setattr__(self, key, value):
    """Set attribute.

    Setting a value on an object of this type will only work for attributes
    defined in ATTRIBUTES.  To make other assignments possible it is necessary
    to override this method in subclasses.

    It is important that assignment is restricted in this way because
    this validation is used as validation for parsing.  Absent this restriction
    it would be possible for method names to be overwritten.

    Args:
      key: Name of attribute to set.
      value: Attributes new value.

    Raises:
      ValidationError: when trying to assign to an attribute
        that does not exist.
    """
    value = self.GetValidator(key)(value, key)
    object.__setattr__(self, key, value)

  def __str__(self):
    """Formatted view of validated object and nested values."""
    return repr(self)

  def __repr__(self):
    """Formatted view of validated object and nested values."""
    values = [(attr, getattr(self, attr)) for attr in self.ATTRIBUTES]
    dent = '    '
    value_list = []
    for attr, value in values:
      value_list.append('\n%s%s=%s' % (dent, attr, value))

    return "<%s %s\n%s>" % (self.__class__.__name__, ' '.join(value_list), dent)

  def __eq__(self, other):
    """Equality operator.

    Comparison is done by comparing all attribute values to those in the other
    instance.  Objects which are not of the same type are not equal.

    Args:
      other: Other object to compare against.

    Returns:
      True if validated objects are equal, else False.
    """
    if type(self) != type(other):
      return False
    for key in self.ATTRIBUTES.iterkeys():
      if getattr(self, key) != getattr(other, key):
        return False
    return True

  def __ne__(self, other):
    """Inequality operator."""
    return not self.__eq__(other)

  def __hash__(self):
    """Hash function for using Validated objects in sets and maps.

    Hash is done by hashing all keys and values and xor'ing them together.

    Returns:
      Hash of validated object.
    """
    result = 0
    for key in self.ATTRIBUTES.iterkeys():
      value = getattr(self, key)
      if isinstance(value, list):
        value = tuple(value)
      result = result ^ hash(key) ^ hash(value)
    return result

  def ToDict(self):
    """Convert Validated object to a dictionary.

    Recursively traverses all of its elements and converts everything to
    simplified collections.

    Returns:
      A dict of all attributes defined in this classes ATTRIBUTES mapped
      to its value.  This structure is recursive in that Validated objects
      that are referenced by this object and in lists are also converted to
      dicts.
    """
    result = {}
    for name, validator in self.ATTRIBUTES.iteritems():
      value = getattr(self, name)

      if not(isinstance(validator, Validator) and value == validator.default):
        result[name] = _SimplifiedValue(validator, value)
    return result


class ValidatedDict(ValidatedBase, dict):
  """Base class for validated dictionaries.

  You can control the keys and values that are allowed in the dictionary
  by setting KEY_VALIDATOR and VALUE_VALIDATOR to subclasses of Validator (or
  things that can be interpreted as validators, see AsValidator).

  For example if you wanted only capitalized keys that map to integers
  you could do:

    class CapitalizedIntegerDict(ValidatedDict):
      KEY_VALIDATOR = Regex('[A-Z].*')
      VALUE_VALIDATOR = int  # this gets interpreted to Type(int)

  The following code would result in an error:

    my_dict = CapitalizedIntegerDict()
    my_dict['lowercase'] = 5  # Throws a validation exception

  You can freely nest Validated and ValidatedDict inside each other so:

    class MasterObject(Validated):
      ATTRIBUTES = {'paramdict': CapitalizedIntegerDict}

  Could be used to parse the following yaml:
    paramdict:
      ArbitraryKey: 323
      AnotherArbitraryKey: 9931
  """
  KEY_VALIDATOR = None
  VALUE_VALIDATOR = None

  def __init__(self, **kwds):
    """Construct a validated dict by interpreting the key and value validators.

    Args:
      **kwds: keyword arguments will be validated and put into the dict.
    """
    self.update(kwds)

  @classmethod
  def GetValidator(self, key):
    """Check the key for validity and return a corresponding value validator.

    Args:
      key: The key that will correspond to the validator we are returning.
    """
    key = AsValidator(self.KEY_VALIDATOR)(key, 'key in %s' % self.__name__)
    return AsValidator(self.VALUE_VALIDATOR)

  def __setitem__(self, key, value):
    """Set an item.

    Only attributes accepted by GetValidator and values that validate
    with the validator returned from GetValidator are allowed to be set
    in this dictionary.

    Args:
      key: Name of item to set.
      value: Items new value.

    Raises:
      ValidationError: when trying to assign to a value that does not exist.
    """
    dict.__setitem__(self, key, self.GetValidator(key)(value, key))

  def setdefault(self, key, value=None):
    """Trap setdefaultss to ensure all key/value pairs are valid.

    See the documentation for setdefault on dict for usage details.

    Raises:
      ValidationError: if the specified key is illegal or the
      value invalid.
    """
    return dict.setdefault(self, key, self.GetValidator(key)(value, key))

  def update(self, other, **kwds):
    """Trap updates to ensure all key/value pairs are valid.

    See the documentation for update on dict for usage details.

    Raises:
      ValidationError: if any of the specified keys are illegal or
        values invalid.
    """
    if hasattr(other, 'keys') and callable(getattr(other, 'keys')):
      newother = {}
      for k in other:
        newother[k] = self.GetValidator(k)(other[k], k)
    else:
      newother = [(k, self.GetValidator(k)(v, k)) for (k, v) in other]

    newkwds = {}
    for k in kwds:
      newkwds[k] = self.GetValidator(k)(kwds[k], k)

    dict.update(self, newother, **newkwds)

  def Set(self, key, value):
    """Set a single value on Validated instance.

    This method checks that a given key and value are valid and if so
    puts the item into this dictionary.

    Args:
      key: The name of the attributes
      value: The value to set

    Raises:
      ValidationError: when no validated attribute exists on class.
    """
    self[key] = value

  def ToDict(self):
    """Convert ValidatedBase object to a dictionary.

    Recursively traverses all of its elements and converts everything to
    simplified collections.

    Subclasses should override this method.

    Returns:
      A dictionary mapping all attributes to simple values or collections.
    """
    result = {}
    for name, value in self.iteritems():
      validator = self.GetValidator(name)
      result[name] = _SimplifiedValue(validator, value)
    return result





class Validator(object):
  """Validator base class.

  Though any callable can be used as a validator, this class encapsulates the
  case when a specific validator needs to hold a particular state or
  configuration.

  To implement Validator sub-class, override the validate method.

  This class is permitted to change the ultimate value that is set to the
  attribute if there is a reasonable way to perform the conversion.
  """

  expected_type = object

  def __init__(self, default=None):
    """Constructor.

    Args:
      default: Default assignment is made during initialization and will
        not pass through validation.
    """
    self.default = default

  def __call__(self, value, key='???'):
    """Main interface to validator is call mechanism."""
    return self.Validate(value, key)

  def Validate(self, value, key='???'):
    """Override this method to customize sub-class behavior.

    Args:
      value: Value to validate.
      key: Name of the field being validated.

    Returns:
      Value if value is valid, or a valid representation of value.
    """
    return value

  def ToValue(self, value):
    """Convert 'value' to a simplified collection or basic type.

    Subclasses of Validator should override this method when the dumped
    representation of 'value' is not simply <type>(value) (e.g. a regex).

    Args:
      value: An object of the same type that was returned from Validate().

    Returns:
      An instance of a builtin type (e.g. int, str, dict, etc).  By default
      it returns 'value' unmodified.
    """
    return value


class Type(Validator):
  """Verifies property is of expected type.

  Can optionally convert value if it is not of the expected type.

  It is possible to specify a required field of a specific type in shorthand
  by merely providing the type.  This method is slightly less efficient than
  providing an explicit type but is not significant unless parsing a large
  amount of information:

    class Person(Validated):
      ATTRIBUTES = {'name': unicode,
                    'age': int,
                    }

  However, in most instances it is best to use the type constants:

    class Person(Validated):
      ATTRIBUTES = {'name': TypeUnicode,
                    'age': TypeInt,
                    }
  """

  def __init__(self, expected_type, convert=True, default=None):
    """Initialize Type validator.

    Args:
      expected_type: Type that attribute should validate against.
      convert: Cause conversion if value is not the right type.
        Conversion is done by calling the constructor of the type
        with the value as its first parameter.
      default: Default assignment is made during initialization and will
        not pass through validation.
    """
    super(Type, self).__init__(default)
    self.expected_type = expected_type
    self.convert = convert

  def Validate(self, value, key):
    """Validate that value has the correct type.

    Args:
      value: Value to validate.
      key: Name of the field being validated.

    Returns:
      value if value is of the correct type. value is coverted to the correct
      type if the Validator is configured to do so.

    Raises:
      MissingAttribute: if value is None and the expected type is not NoneType.
      ValidationError: if value is not of the right type and the validator
        is either configured not to convert or cannot convert.
    """
    if not isinstance(value, self.expected_type):
      if value is None:
        raise MissingAttribute('Missing value is required.')

      if self.convert:
        try:
          return self.expected_type(value)
        except ValueError, e:
          raise ValidationError(
              'Value %r for %s could not be converted to type %s.' % (
                  value, key, self.expected_type.__name__), e)
        except TypeError, e:
          raise ValidationError(
              'Value %r for %s is not of the expected type %s' % (
                  value, key, self.expected_type.__name__), e)
      else:
        raise ValidationError(
              'Value %r for %s is not of the expected type %s' % (
                  value, key, self.expected_type.__name__))
    else:
      return value


TYPE_BOOL = Type(bool)
TYPE_INT = Type(int)
TYPE_LONG = Type(long)
TYPE_STR = Type(str)
TYPE_UNICODE = Type(unicode)
TYPE_FLOAT = Type(float)


class Options(Validator):
  """Limit field based on pre-determined values.

  Options are used to make sure an enumerated set of values are the only
  one permitted for assignment.  It is possible to define aliases which
  map multiple string values to a single original.  An example of usage:

    class ZooAnimal(validated.Class):
      ATTRIBUTES = {
        'name': str,
        'kind': Options('platypus',                   # No aliases
                        ('rhinoceros', ['rhino']),    # One alias
                        ('canine', ('dog', 'puppy')), # Two aliases
                        )
  """

  def __init__(self, *options, **kw):
    """Initialize options.

    Args:
      options: List of allowed values.
    """
    if 'default' in kw:
      default = kw['default']
    else:
      default = None

    alias_map = {}
    def AddAlias(alias, original):
      """Set new alias on alias_map.

      Raises:
        AttributeDefinitionError: when option already exists or if alias is
          not of type str.
      """
      if not isinstance(alias, str):
        raise AttributeDefinitionError(
            'All option values must be of type str.')
      elif alias in alias_map:
        raise AttributeDefinitionError(
            "Option '%s' already defined for options property." % alias)
      alias_map[alias] = original


    for option in options:
      if isinstance(option, str):
        AddAlias(option, option)

      elif isinstance(option, (list, tuple)):

        if len(option) != 2:
          raise AttributeDefinitionError("Alias is defined as a list of tuple "
                                         "with two items.  The first is the "
                                         "original option, while the second "
                                         "is a list or tuple of str aliases.\n"
                                         "\n  Example:\n"
                                         "      ('original', ('alias1', "
                                         "'alias2'")
        original, aliases = option
        AddAlias(original, original)
        if not isinstance(aliases, (list, tuple)):
          raise AttributeDefinitionError('Alias lists must be a list or tuple')

        for alias in aliases:
          AddAlias(alias, original)

      else:
        raise AttributeDefinitionError("All options must be of type str "
                                       "or of the form (str, [str...]).")
    super(Options, self).__init__(default)
    self.options = alias_map

  def Validate(self, value, key):
    """Validate options.

    Returns:
      Original value for provided alias.

    Raises:
      ValidationError: when value is not one of predefined values.
    """
    if value is None:
      raise ValidationError('Value for options field must not be None.')
    value = str(value)
    if value not in self.options:
      raise ValidationError('Value \'%s\' for %s not in %s.'
                            % (value, key, self.options))
    return self.options[value]


class Optional(Validator):
  """Definition of optional attributes.

  Optional values are attributes which can be set to None or left
  unset.  All values in a basic Validated class are set to None
  at initialization.  Failure to assign to non-optional values
  will result in a validation error when calling CheckInitialized.
  """

  def __init__(self, validator, default=None):
    """Initializer.

    This constructor will make a few guesses about the value passed in
    as the validator:

      - If the validator argument is a type, it automatically creates a Type
        validator around it.

      - If the validator argument is a list or tuple, it automatically
        creates an Options validator around it.

    Args:
      validator: Optional validation condition.

    Raises:
      AttributeDefinitionError: if validator is not callable.
    """
    self.validator = AsValidator(validator)
    self.expected_type = self.validator.expected_type
    self.default = default

  def Validate(self, value, key):
    """Optionally require a value.

    Normal validators do not accept None.  This will accept none on
    behalf of the contained validator.

    Args:
      value: Value to be validated as optional.
      key: Name of the field being validated.

    Returns:
      None if value is None, else results of contained validation.
    """
    if value is None:
      return None
    return self.validator(value, key)

  def ToValue(self, value):
    """Convert 'value' to a simplified collection or basic type."""
    if value is None:
      return None
    return self.validator.ToValue(value)


class Regex(Validator):
  """Regular expression validator.

  Regular expression validator always converts value to string.  Note that
  matches must be exact.  Partial matches will not validate.  For example:

    class ClassDescr(Validated):
      ATTRIBUTES = { 'name': Regex(r'[a-zA-Z_][a-zA-Z_0-9]*'),
                     'parent': Type(type),
                     }

  Alternatively, any attribute that is defined as a string is automatically
  interpreted to be of type Regex.  It is possible to specify unicode regex
  strings as well.  This approach is slightly less efficient, but usually
  is not significant unless parsing large amounts of data:

    class ClassDescr(Validated):
      ATTRIBUTES = { 'name': r'[a-zA-Z_][a-zA-Z_0-9]*',
                     'parent': Type(type),
                     }

    # This will raise a ValidationError exception.
    my_class(name='AName with space', parent=AnotherClass)
  """

  def __init__(self, regex, string_type=unicode, default=None):
    """Initialized regex validator.

    Args:
      regex: Regular expression string to use for comparison.

    Raises:
      AttributeDefinitionError: if string_type is not a kind of string.
    """
    super(Regex, self).__init__(default)
    if (not issubclass(string_type, basestring) or
        string_type is basestring):
      raise AttributeDefinitionError(
          'Regex fields must be a string type not %s.' % str(string_type))
    if isinstance(regex, basestring):
      self.re = re.compile('^(?:%s)$' % regex)
    else:
      raise AttributeDefinitionError(
          'Regular expression must be string.  Found %s.' % str(regex))

    self.expected_type = string_type

  def Validate(self, value, key):
    """Does validation of a string against a regular expression.

    Args:
      value: String to match against regular expression.
      key: Name of the field being validated.

    Raises:
      ValidationError: when value does not match regular expression or
        when value does not match provided string type.
    """
    if issubclass(self.expected_type, str):
      cast_value = TYPE_STR(value)
    else:
      cast_value = TYPE_UNICODE(value)

    if self.re.match(cast_value) is None:
      raise ValidationError('Value \'%s\' for %s does not match expression '
                            '\'%s\'' % (value, key, self.re.pattern))
    return cast_value


class _RegexStrValue(object):
  """Simulates the regex object to support recompilation when necessary.

  Used by the RegexStr class to dynamically build and recompile regular
  expression attributes of a validated object.  This object replaces the normal
  object returned from re.compile which is immutable.

  When the value of this object is a string, that string is simply used as the
  regular expression when recompilation is needed.  If the state of this object
  is a list of strings, the strings are joined in to a single 'or' expression.
  """

  def __init__(self, attribute, value, key):
    """Initialize recompilable regex value.

    Args:
      attribute: Attribute validator associated with this regex value.
      value: Initial underlying python value for regex string.  Either a single
        regex string or a list of regex strings.
      key: Name of the field.
    """
    self.__attribute = attribute
    self.__value = value
    self.__regex = None
    self.__key = key

  def __AsString(self, value):
    """Convert a value to appropriate string.

    Returns:
      String version of value with all carriage returns and line feeds removed.
    """
    if issubclass(self.__attribute.expected_type, str):
      cast_value = TYPE_STR(value)
    else:
      cast_value = TYPE_UNICODE(value)

    cast_value = cast_value.replace('\n', '')
    cast_value = cast_value.replace('\r', '')
    return cast_value

  def __BuildRegex(self):
    """Build regex string from state.

    Returns:
      String version of regular expression.  Sequence objects are constructed
      as larger regular expression where each regex in the list is joined with
      all the others as single 'or' expression.
    """
    if isinstance(self.__value, list):
      value_list = self.__value
      sequence = True
    else:
      value_list = [self.__value]
      sequence = False

    regex_list = []
    for item in value_list:
      regex_list.append(self.__AsString(item))

    if sequence:
      return '|'.join('%s' % item for item in regex_list)
    else:
      return regex_list[0]

  def __Compile(self):
    """Build regular expression object from state.

    Returns:
      Compiled regular expression based on internal value.
    """
    regex = self.__BuildRegex()
    try:
      return re.compile(regex)
    except re.error, e:
      raise ValidationError('Value \'%s\' for %s does not compile: %s' %
                            (regex, self.__key, e), e)

  @property
  def regex(self):
    """Compiled regular expression as described by underlying value."""
    return self.__Compile()

  def match(self, value):
    """Match against internal regular expression.

    Returns:
      Regular expression object built from underlying value.
    """
    return re.match(self.__BuildRegex(), value)

  def Validate(self):
    """Ensure that regex string compiles."""
    self.__Compile()

  def __str__(self):
    """Regular expression string as described by underlying value."""
    return self.__BuildRegex()

  def __eq__(self, other):
    """Comparison against other regular expression string values."""
    if isinstance(other, _RegexStrValue):
      return self.__BuildRegex() == other.__BuildRegex()
    return str(self) == other

  def __ne__(self, other):
    """Inequality operator for regular expression string value."""
    return not self.__eq__(other)


class RegexStr(Validator):
  """Validates that a string can compile as a regex without errors.

  Use this validator when the value of a field should be a regex.  That
  means that the value must be a string that can be compiled by re.compile().
  The attribute will then be a compiled re object.
  """

  def __init__(self, string_type=unicode, default=None):
    """Initialized regex validator.

    Raises:
      AttributeDefinitionError: if string_type is not a kind of string.
    """
    if default is not None:
      default = _RegexStrValue(self, default, None)
      re.compile(str(default))
    super(RegexStr, self).__init__(default)
    if (not issubclass(string_type, basestring) or
        string_type is basestring):
      raise AttributeDefinitionError(
          'RegexStr fields must be a string type not %s.' % str(string_type))

    self.expected_type = string_type

  def Validate(self, value, key):
    """Validates that the string compiles as a regular expression.

    Because the regular expression might have been expressed as a multiline
    string, this function also strips newlines out of value.

    Args:
      value: String to compile as a regular expression.
      key: Name of the field being validated.

    Raises:
      ValueError when value does not compile as a regular expression.  TypeError
      when value does not match provided string type.
    """
    if isinstance(value, _RegexStrValue):
      return value
    value = _RegexStrValue(self, value, key)
    value.Validate()
    return value

  def ToValue(self, value):
    """Returns the RE pattern for this validator."""
    return str(value)


class Range(Validator):
  """Validates that numbers fall within the correct range.

  In theory this class can be emulated using Options, however error
  messages generated from that class will not be very intelligible.
  This class essentially does the same thing, but knows the intended
  integer range.

  Also, this range class supports floats and other types that implement
  ordinality.

  The range is inclusive, meaning 3 is considered in the range
  in Range(1,3).
  """

  def __init__(self, minimum, maximum, range_type=int, default=None):
    """Initializer for range.

    At least one of minimum and maximum must be supplied.

    Args:
      minimum: Minimum for attribute.
      maximum: Maximum for attribute.
      range_type: Type of field.  Defaults to int.

    Raises:
      AttributeDefinitionError: if the specified parameters are incorrect.
    """
    super(Range, self).__init__(default)
    if minimum is None and maximum is None:
      raise AttributeDefinitionError('Must specify minimum or maximum.')
    if minimum is not None and not isinstance(minimum, range_type):
      raise AttributeDefinitionError(
          'Minimum value must be of type %s, instead it is %s (%s).' %
          (str(range_type), str(type(minimum)), str(minimum)))
    if maximum is not None and not isinstance(maximum, range_type):
      raise AttributeDefinitionError(
          'Maximum value must be of type %s, instead it is %s (%s).' %
          (str(range_type), str(type(maximum)), str(maximum)))

    self.minimum = minimum
    self.maximum = maximum
    self.expected_type = range_type
    self._type_validator = Type(range_type)

  def Validate(self, value, key):
    """Validate that value is within range.

    Validates against range-type then checks the range.

    Args:
      value: Value to validate.
      key: Name of the field being validated.

    Raises:
      ValidationError: when value is out of range.  ValidationError when value
      is not of the same range type.
    """
    cast_value = self._type_validator.Validate(value, key)
    if self.maximum is None and cast_value < self.minimum:
      raise ValidationError('Value \'%s\' for %s less than %s'
                            % (value, key, self.minimum))
    elif self.minimum is None and cast_value > self.maximum:
      raise ValidationError('Value \'%s\' for %s greater than %s'
                            % (value, key, self.maximum))

    elif ((self.minimum is not None and cast_value < self.minimum) or
          (self.maximum is not None and cast_value > self.maximum)):
      raise ValidationError('Value \'%s\' for %s is out of range %s - %s'
                            % (value, key, self.minimum, self.maximum))
    return cast_value


class Repeated(Validator):
  """Repeated field validator.

  Indicates that attribute is expected to be a repeated value, ie,
  a sequence.  This adds additional validation over just Type(list)
  in that it retains information about what can be stored in the list by
  use of its constructor field.
  """

  def __init__(self, constructor, default=None):
    """Initializer for repeated field.

    Args:
      constructor: Type used for verifying elements of sequence attribute.
    """
    super(Repeated, self).__init__(default)
    self.constructor = constructor
    self.expected_type = list

  def Validate(self, value, key):
    """Do validation of sequence.

    Value must be a list and all elements must be of type 'constructor'.

    Args:
      value: Value to validate.
      key: Name of the field being validated.

    Raises:
      ValidationError: if value is None, not a list or one of its elements is
        the wrong type.
    """
    if not isinstance(value, list):
      raise ValidationError('Value \'%s\' for %s should be a sequence but '
                            'is not.' % (value, key))

    for item in value:
      if isinstance(self.constructor, Validator):
        item = self.constructor.Validate(item, key)
      elif not isinstance(item, self.constructor):
        raise ValidationError('Value element \'%s\' for %s must be type %s.' % (
            str(item), key, self.constructor.__name__))

    return value


class TimeValue(Validator):
  """Validates time values with units, such as 1h or 3.5d."""

  _EXPECTED_SYNTAX = ('must be a non-negative number followed by a time unit, '
                      'such as 1h or 3.5d')

  def __init__(self):
    super(TimeValue, self).__init__()
    self.expected_type = str

  def Validate(self, value, key):
    """Validate a time value.

    Args:
      value: Value to validate.
      key: Name of the field being validated.

    Raises:
      ValidationError: if value is not a time value with the expected format.
    """
    if not isinstance(value, basestring):
      raise ValidationError("Value '%s' for %s is not a string (%s)"
                            % (value, key, TimeValue._EXPECTED_SYNTAX))
    if not value:
      raise ValidationError("Value for %s is empty (%s)"
                            % (key, TimeValue._EXPECTED_SYNTAX))
    if value[-1] not in "smhd":
      raise ValidationError("Value '%s' for %s must end with a time unit, "
                            "one of s (seconds), m (minutes), h (hours), "
                            "or d (days)" % (value, key))
    try:
      t = float(value[:-1])
    except ValueError:
      raise ValidationError("Value '%s' for %s is not a valid time value (%s)"
                            % (value, key, TimeValue._EXPECTED_SYNTAX))
    if t < 0:
      raise ValidationError("Value '%s' for %s is negative (%s)"
                            % (value, key, TimeValue._EXPECTED_SYNTAX))
    return value
