#!/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
