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





"""Higher-level, semantic data types for the datastore. These types
are expected to be set as attributes of Entities.  See "Supported Data Types"
in the API Guide.

Most of these types are based on XML elements from Atom and GData elements
from the atom and gd namespaces. For more information, see:

  http://www.atomenabled.org/developers/syndication/
  http://code.google.com/apis/gdata/common-elements.html

The namespace schemas are:

  http://www.w3.org/2005/Atom
  http://schemas.google.com/g/2005
"""









import base64
import calendar
import datetime
import os
import re
import string
import time
import urlparse
from xml.sax import saxutils

from google.appengine.datastore import entity_pb

from google.appengine.api import datastore_errors
from google.appengine.api import namespace_manager
from google.appengine.api import users
from google.appengine.datastore import datastore_pb
from google.appengine.datastore import datastore_pbs
from google.appengine.datastore import entity_v4_pb
from google.appengine.datastore import sortable_pb_encoder






_MAX_STRING_LENGTH = 500










_MAX_LINK_PROPERTY_LENGTH = 2083





_MAX_RAW_PROPERTY_BYTES = 1000 * 1000







RESERVED_PROPERTY_NAME = re.compile('^__.*__$')







KEY_SPECIAL_PROPERTY = '__key__'
_KEY_SPECIAL_PROPERTY = KEY_SPECIAL_PROPERTY
_UNAPPLIED_LOG_TIMESTAMP_SPECIAL_PROPERTY = '__unapplied_log_timestamp_us__'
SCATTER_SPECIAL_PROPERTY = '__scatter__'
_SPECIAL_PROPERTIES = frozenset(
    [KEY_SPECIAL_PROPERTY,
     _UNAPPLIED_LOG_TIMESTAMP_SPECIAL_PROPERTY,
     SCATTER_SPECIAL_PROPERTY])







_NAMESPACE_SEPARATOR = '!'





_EMPTY_NAMESPACE_ID = 1


_EPOCH = datetime.datetime.utcfromtimestamp(0)





class UtcTzinfo(datetime.tzinfo):
  def utcoffset(self, dt): return datetime.timedelta(0)
  def dst(self, dt): return datetime.timedelta(0)
  def tzname(self, dt): return 'UTC'
  def __repr__(self): return 'datastore_types.UTC'

UTC = UtcTzinfo()


def typename(obj):
  """Returns the type of obj as a string. More descriptive and specific than
  type(obj), and safe for any object, unlike __class__."""
  if hasattr(obj, '__class__'):
    return getattr(obj, '__class__').__name__
  else:
    return type(obj).__name__


def ValidateString(value,
                   name='unused',
                   exception=datastore_errors.BadValueError,
                   max_len=_MAX_STRING_LENGTH,
                   empty_ok=False):
  """Raises an exception if value is not a valid string or a subclass thereof.

  A string is valid if it's not empty, no more than _MAX_STRING_LENGTH bytes,
  and not a Blob. The exception type can be specified with the exception
  argument; it defaults to BadValueError.

  Args:
    value: the value to validate.
    name: the name of this value; used in the exception message.
    exception: the type of exception to raise.
    max_len: the maximum allowed length, in bytes.
    empty_ok: allow empty value.
  """
  if value is None and empty_ok:
    return
  if not isinstance(value, basestring) or isinstance(value, Blob):
    raise exception('%s should be a string; received %s (a %s):' %
                    (name, value, typename(value)))
  if not value and not empty_ok:
    raise exception('%s must not be empty.' % name)

  if len(value.encode('utf-8')) > max_len:
    raise exception('%s must be under %d bytes.' % (name, max_len))


def ValidateInteger(value,
                   name='unused',
                   exception=datastore_errors.BadValueError,
                   empty_ok=False,
                   zero_ok=False,
                   negative_ok=False):
  """Raises an exception if value is not a valid integer.

  An integer is valid if it's not negative or empty and is an integer
  (either int or long).  The exception type raised can be specified
  with the exception argument; it defaults to BadValueError.

  Args:
    value: the value to validate.
    name: the name of this value; used in the exception message.
    exception: the type of exception to raise.
    empty_ok: allow None value.
    zero_ok: allow zero value.
    negative_ok: allow negative value.
  """
  if value is None and empty_ok:
    return
  if not isinstance(value, (int, long)):
    raise exception('%s should be an integer; received %s (a %s).' %
                    (name, value, typename(value)))
  if not value and not zero_ok:
    raise exception('%s must not be 0 (zero)' % name)
  if value < 0 and not negative_ok:
    raise exception('%s must not be negative.' % name)

def ResolveAppId(app):
  """Validate app id, providing a default.

  If the argument is None, $APPLICATION_ID is substituted.

  Args:
    app: The app id argument value to be validated.

  Returns:
    The value of app, or the substituted default.  Always a non-empty string.

  Raises:
    BadArgumentError if the value is empty or not a string.
  """
  if app is None:
    app = os.environ.get('APPLICATION_ID', '')
  ValidateString(app, 'app', datastore_errors.BadArgumentError)
  return app


def ResolveNamespace(namespace):
  """Validate app namespace, providing a default.

  If the argument is None, namespace_manager.get_namespace() is substituted.

  Args:
    namespace: The namespace argument value to be validated.

  Returns:
    The value of namespace, or the substituted default. The empty string is used
    to denote the empty namespace.

  Raises:
    BadArgumentError if the value is not a string.
  """
  if namespace is None:
    namespace = namespace_manager.get_namespace()
  else:
    namespace_manager.validate_namespace(
        namespace, datastore_errors.BadArgumentError)
  return namespace


def EncodeAppIdNamespace(app_id, namespace):
  """Concatenates app id and namespace into a single string.

  This method is needed for xml and datastore_file_stub.

  Args:
    app_id: The application id to encode
    namespace: The namespace to encode

  Returns:
    The string encoding for the app_id, namespace pair.
  """
  if not namespace:
    return app_id
  else:
    return app_id + _NAMESPACE_SEPARATOR + namespace


def DecodeAppIdNamespace(app_namespace_str):
  """Decodes app_namespace_str into an (app_id, namespace) pair.

  This method is the reverse of EncodeAppIdNamespace and is needed for
  datastore_file_stub.

  Args:
    app_namespace_str: An encoded app_id, namespace pair created by
      EncodeAppIdNamespace

  Returns:
    (app_id, namespace) pair encoded in app_namespace_str
  """
  sep = app_namespace_str.find(_NAMESPACE_SEPARATOR)
  if sep < 0:
    return (app_namespace_str, '')
  else:
    return (app_namespace_str[0:sep], app_namespace_str[sep + 1:])


def SetNamespace(proto, namespace):
  """Sets the namespace for a protocol buffer or clears the field.

  Args:
    proto: the protocol buffer to update
    namespace: the new namespace (None or an empty string will clear out the
        field).
  """
  if not namespace:
    proto.clear_name_space()
  else:
    proto.set_name_space(namespace)


def PartitionString(value, separator):
  """Equivalent to python2.5 str.partition()
     TODO use str.partition() when python 2.5 is adopted.

  Args:
    value: String to be partitioned
    separator: Separator string
  """
  index = value.find(separator)
  if index == -1:
    return (value, '', value[0:0])
  else:
    return (value[0:index], separator, value[index+len(separator):len(value)])



class Key(object):
  """The primary key for a datastore entity.

  A datastore GUID. A Key instance uniquely identifies an entity across all
  apps, and includes all information necessary to fetch the entity from the
  datastore with Get().

  Key implements __hash__, and key instances are immutable, so Keys may be
  used in sets and as dictionary keys.
  """
  __reference = None

  def __init__(self, encoded=None):
    """Constructor. Creates a Key from a string.

    Args:
      # a base64-encoded primary key, generated by Key.__str__
      encoded: str
    """
    self._str = None
    if encoded is not None:
      if not isinstance(encoded, basestring):
        try:
          repr_encoded = repr(encoded)
        except:
          repr_encoded = "<couldn't encode>"
        raise datastore_errors.BadArgumentError(
          'Key() expects a string; received %s (a %s).' %
          (repr_encoded, typename(encoded)))
      try:

        modulo = len(encoded) % 4
        if modulo != 0:
          encoded += ('=' * (4 - modulo))







        self._str = str(encoded)
        encoded_pb = base64.urlsafe_b64decode(self._str)
        self.__reference = entity_pb.Reference(encoded_pb)
        assert self.__reference.IsInitialized()


        self._str = self._str.rstrip('=')

      except (AssertionError, TypeError), e:
        raise datastore_errors.BadKeyError(
          'Invalid string key %s. Details: %s' % (encoded, e))
      except Exception, e:





        if e.__class__.__name__ == 'ProtocolBufferDecodeError':
          raise datastore_errors.BadKeyError('Invalid string key %s.' % encoded)
        else:
          raise
    else:

      self.__reference = entity_pb.Reference()

  def to_path(self, _default_id=None, _decode=True, _fail=True):
    """Construct the "path" of this key as a list.

    Returns:
      A list [kind_1, id_or_name_1, ..., kind_n, id_or_name_n] of the key path.

    Raises:
      datastore_errors.BadKeyError if this key does not have a valid path.
    """






    def Decode(s):
      if _decode:
        try:
          return s.decode('utf-8')
        except UnicodeDecodeError:
          if _fail:
            raise
      return s

    path = []
    for path_element in self.__reference.path().element_list():
      path.append(Decode(path_element.type()))
      if path_element.has_name():
        path.append(Decode(path_element.name()))
      elif path_element.has_id():
        path.append(path_element.id())
      elif _default_id is not None:
        path.append(_default_id)
      else:
        raise datastore_errors.BadKeyError('Incomplete key found in to_path')
    return path

  @staticmethod
  def from_path(*args, **kwds):
    """Static method to construct a Key out of a "path" (kind, id or name, ...).

    This is useful when an application wants to use just the id or name portion
    of a key in e.g. a URL, where the rest of the URL provides enough context to
    fill in the rest, i.e. the app id (always implicit), the entity kind, and
    possibly an ancestor key. Since ids and names are usually small, they're
    more attractive for use in end-user-visible URLs than the full string
    representation of a key.

    Args:
      kind: the entity kind (a str or unicode instance)
      id_or_name: the id (an int or long) or name (a str or unicode instance)
      parent: optional parent Key; default None.
      namespace: optional namespace to use otherwise namespace_manager's
        default namespace is used.

    Returns:
      A new Key instance whose .kind() and .id() or .name() methods return
      the *last* kind and id or name positional arguments passed.

    Raises:
      BadArgumentError for invalid arguments.
      BadKeyError if the parent key is incomplete.
    """

    parent = kwds.pop('parent', None)

    app_id = ResolveAppId(kwds.pop('_app', None))



    namespace = kwds.pop('namespace', None)


    if kwds:
      raise datastore_errors.BadArgumentError(
          'Excess keyword arguments ' + repr(kwds))


    if not args or len(args) % 2:
      raise datastore_errors.BadArgumentError(
          'A non-zero even number of positional arguments is required '
          '(kind, id or name, kind, id or name, ...); received %s' % repr(args))


    if parent is not None:
      if not isinstance(parent, Key):
        raise datastore_errors.BadArgumentError(
            'Expected None or a Key as parent; received %r (a %s).' %
            (parent, typename(parent)))
      if namespace is None:
        namespace = parent.namespace()
      if not parent.has_id_or_name():
        raise datastore_errors.BadKeyError(
            'The parent Key is incomplete.')
      if app_id != parent.app() or namespace != parent.namespace():
        raise datastore_errors.BadArgumentError(
            'The app/namespace arguments (%s/%s) should match '
            'parent.app/namespace() (%s/%s)' %
            (app_id, namespace, parent.app(), parent.namespace()))


    namespace = ResolveNamespace(namespace)


    key = Key()
    ref = key.__reference
    if parent is not None:
      ref.CopyFrom(parent.__reference)
    else:
      ref.set_app(app_id)
      SetNamespace(ref, namespace)



    path = ref.mutable_path()
    for i in xrange(0, len(args), 2):
      kind, id_or_name = args[i:i+2]
      if isinstance(kind, basestring):
        kind = kind.encode('utf-8')
      else:
        raise datastore_errors.BadArgumentError(
            'Expected a string kind as argument %d; received %r (a %s).' %
            (i + 1, kind, typename(kind)))
      elem = path.add_element()
      elem.set_type(kind)
      if isinstance(id_or_name, (int, long)):
        elem.set_id(id_or_name)
      elif isinstance(id_or_name, basestring):
        ValidateString(id_or_name, 'name')
        elem.set_name(id_or_name.encode('utf-8'))
      else:
        raise datastore_errors.BadArgumentError(
            'Expected an integer id or string name as argument %d; '
            'received %r (a %s).' % (i + 2, id_or_name, typename(id_or_name)))


    assert ref.IsInitialized()
    return key

  def app(self):
    """Returns this entity's app id, a string."""
    if self.__reference.app():
      return self.__reference.app().decode('utf-8')
    else:
      return None

  def namespace(self):
    """Returns this entity's namespace, a string."""
    if self.__reference.has_name_space():
      return self.__reference.name_space().decode('utf-8')
    else:
      return ''



  def kind(self):
    """Returns this entity's kind, as a string."""
    if self.__reference.path().element_size() > 0:
      encoded = self.__reference.path().element_list()[-1].type()
      return unicode(encoded.decode('utf-8'))
    else:
      return None

  def id(self):
    """Returns this entity's id, or None if it doesn't have one."""
    elems = self.__reference.path().element_list()
    if elems and elems[-1].has_id() and elems[-1].id():
      return elems[-1].id()
    else:
      return None

  def name(self):
    """Returns this entity's name, or None if it doesn't have one."""
    elems = self.__reference.path().element_list()
    if elems and elems[-1].has_name() and elems[-1].name():
      return elems[-1].name().decode('utf-8')
    else:
      return None

  def id_or_name(self):
    """Returns this entity's id or name, whichever it has, or None."""
    if self.id() is not None:
      return self.id()
    else:

      return self.name()

  def has_id_or_name(self):
    """Returns True if this entity has an id or name, False otherwise.
    """
    elems = self.__reference.path().element_list()
    if elems:
      e = elems[-1]
      return bool(e.name() or e.id())
    else:
      return False

  def parent(self):
    """Returns this entity's parent, as a Key. If this entity has no parent,
    returns None."""
    if self.__reference.path().element_size() > 1:
      parent = Key()
      parent.__reference.CopyFrom(self.__reference)
      del parent.__reference.path().element_list()[-1]
      return parent
    else:
      return None

  def ToTagUri(self):
    """Returns a tag: URI for this entity for use in XML output.

    Foreign keys for entities may be represented in XML output as tag URIs.
    RFC 4151 describes the tag URI scheme. From http://taguri.org/:

      The tag algorithm lets people mint - create - identifiers that no one
      else using the same algorithm could ever mint. It is simple enough to do
      in your head, and the resulting identifiers can be easy to read, write,
      and remember. The identifiers conform to the URI (URL) Syntax.

    Tag URIs for entities use the app's auth domain and the date that the URI
     is generated. The namespace-specific part is <kind>[<key>].

    For example, here is the tag URI for a Kitten with the key "Fluffy" in the
    catsinsinks app:

      tag:catsinsinks.googleapps.com,2006-08-29:Kitten[Fluffy]

    Raises a BadKeyError if this entity's key is incomplete.
    """
    if not self.has_id_or_name():
      raise datastore_errors.BadKeyError(
        'ToTagUri() called for an entity with an incomplete key.')

    return u'tag:%s.%s,%s:%s[%s]' % (

        saxutils.escape(EncodeAppIdNamespace(self.app(), self.namespace())),
        os.environ['AUTH_DOMAIN'],
        datetime.date.today().isoformat(),
        saxutils.escape(self.kind()),
        saxutils.escape(str(self)))

  ToXml = ToTagUri

  def entity_group(self):
    """Returns this key's entity group as a Key.

    Note that the returned Key will be incomplete if this Key is for a root
    entity and it is incomplete.
    """
    group = Key._FromPb(self.__reference)
    del group.__reference.path().element_list()[1:]
    return group

  @staticmethod
  def _FromPb(pb):
    """Static factory method. Creates a Key from an entity_pb.Reference.

    Not intended to be used by application developers. Enforced by hiding the
    entity_pb classes.

    Args:
      pb: entity_pb.Reference
    """
    if not isinstance(pb, entity_pb.Reference):
      raise datastore_errors.BadArgumentError(
        'Key constructor takes an entity_pb.Reference; received %s (a %s).' %
        (pb, typename(pb)))

    key = Key()
    key.__reference = entity_pb.Reference()
    key.__reference.CopyFrom(pb)
    return key

  def _ToPb(self):
    """Converts this Key to its protocol buffer representation.

    Not intended to be used by application developers. Enforced by hiding the
    entity_pb classes.

    Returns:
      # the Reference PB representation of this Key
      entity_pb.Reference
    """
    pb = entity_pb.Reference()
    pb.CopyFrom(self.__reference)



    pb.app().decode('utf-8')
    for pathelem in pb.path().element_list():
      pathelem.type().decode('utf-8')

    return pb

  def __str__(self):
    """Encodes this Key as an opaque string.

    Returns a string representation of this key, suitable for use in HTML,
    URLs, and other similar use cases. If the entity's key is incomplete,
    raises a BadKeyError.

    Unfortunately, this string encoding isn't particularly compact, and its
    length varies with the length of the path. If you want a shorter identifier
    and you know the kind and parent (if any) ahead of time, consider using just
    the entity's id or name.

    Returns:
      string
    """



    try:
      if self._str is not None:
        return self._str
    except AttributeError:
      pass
    if (self.has_id_or_name()):
      encoded = base64.urlsafe_b64encode(self.__reference.Encode())
      self._str = encoded.replace('=', '')
    else:
      raise datastore_errors.BadKeyError(
        'Cannot string encode an incomplete key!\n%s' % self.__reference)
    return self._str


  def __repr__(self):
    """Returns an eval()able string representation of this key.

    Returns a Python string of the form 'datastore_types.Key.from_path(...)'
    that can be used to recreate this key.

    Returns:
      string
    """
    args = []
    for elem in self.__reference.path().element_list():
      args.append(repr(elem.type().decode('utf-8')))
      if elem.has_name():
        args.append(repr(elem.name().decode('utf-8')))
      else:
        args.append(repr(elem.id()))

    args.append('_app=%r' % self.__reference.app().decode('utf-8'))
    if self.__reference.has_name_space():
      args.append('namespace=%r' %
          self.__reference.name_space().decode('utf-8'))
    return u'datastore_types.Key.from_path(%s)' % ', '.join(args)

  def __cmp__(self, other):
    """Returns negative, zero, or positive when comparing two keys.

    TODO: for API v2, we should change this to make incomplete keys, ie
    keys without an id or name, not equal to any other keys.

    Args:
      other: Key to compare to.

    Returns:
      Negative if self is less than "other"
      Zero if "other" is equal to self
      Positive if self is greater than "other"
    """
    if not isinstance(other, Key):
      return -2

    self_args = [self.__reference.app(), self.__reference.name_space()]
    self_args += self.to_path(_default_id=0, _decode=False)

    other_args = [other.__reference.app(), other.__reference.name_space()]
    other_args += other.to_path(_default_id=0, _decode=False)

    for self_component, other_component in zip(self_args, other_args):
      comparison = cmp(self_component, other_component)
      if comparison != 0:
        return comparison

    return cmp(len(self_args), len(other_args))

  def __hash__(self):
    """Returns an integer hash of this key.

    Implements Python's hash protocol so that Keys may be used in sets and as
    dictionary keys.

    Returns:
      int
    """
    args = self.to_path(_default_id=0, _fail=False)
    args.append(self.__reference.app())
    return hash(type(args)) ^ hash(tuple(args))


class _OverflowDateTime(long):
  """Container for GD_WHEN values that don't fit into a datetime.datetime.

  This class only exists to safely round-trip GD_WHEN values that are too large
  to fit in a datetime.datetime instance e.g. that were created by Java
  applications. It should not be created directly.
  """
  pass


def _When(val):
  """Coverts a GD_WHEN value to the appropriate type."""
  try:
    return _EPOCH + datetime.timedelta(microseconds=val)
  except OverflowError:
    return _OverflowDateTime(val)










class Category(unicode):
  """A tag, ie a descriptive word or phrase. Entities may be tagged by users,
  and later returned by a queries for that tag. Tags can also be used for
  ranking results (frequency), photo captions, clustering, activity, etc.

  Here's a more in-depth description:  http://www.zeldman.com/daily/0405d.shtml

  This is the Atom "category" element. In XML output, the tag is provided as
  the term attribute. See:
  http://www.atomenabled.org/developers/syndication/#category

  Raises BadValueError if tag is not a string or subtype.
  """
  TERM = 'user-tag'

  def __init__(self, tag):
    super(Category, self).__init__()
    ValidateString(tag, 'tag')

  def ToXml(self):
    return u'<category term="%s" label=%s />' % (Category.TERM,
                                                 saxutils.quoteattr(self))


class Link(unicode):
  """A fully qualified URL. Usually http: scheme, but may also be file:, ftp:,
  news:, among others.

  If you have email (mailto:) or instant messaging (aim:, xmpp:) links,
  consider using the Email or IM classes instead.

  This is the Atom "link" element. In XML output, the link is provided as the
  href attribute. See:
  http://www.atomenabled.org/developers/syndication/#link

  Raises BadValueError if link is not a fully qualified, well-formed URL.
  """
  def __init__(self, link):
    super(Link, self).__init__()
    ValidateString(link, 'link', max_len=_MAX_LINK_PROPERTY_LENGTH)

    scheme, domain, path, params, query, fragment = urlparse.urlparse(link)
    if (not scheme or (scheme != 'file' and not domain) or
                      (scheme == 'file' and not path)):
      raise datastore_errors.BadValueError('Invalid URL: %s' % link)

  def ToXml(self):
    return u'<link href=%s />' % saxutils.quoteattr(self)


class Email(unicode):
  """An RFC2822 email address. Makes no attempt at validation; apart from
  checking MX records, email address validation is a rathole.

  This is the gd:email element. In XML output, the email address is provided as
  the address attribute. See:
  http://code.google.com/apis/gdata/common-elements.html#gdEmail

  Raises BadValueError if email is not a valid email address.
  """
  def __init__(self, email):
    super(Email, self).__init__()
    ValidateString(email, 'email')

  def ToXml(self):
    return u'<gd:email address=%s />' % saxutils.quoteattr(self)


class GeoPt(object):
  """A geographical point, specified by floating-point latitude and longitude
  coordinates. Often used to integrate with mapping sites like Google Maps.
  May also be used as ICBM coordinates.

  This is the georss:point element. In XML output, the coordinates are
  provided as the lat and lon attributes. See: http://georss.org/

  Serializes to '<lat>,<lon>'. Raises BadValueError if it's passed an invalid
  serialized string, or if lat and lon are not valid floating points in the
  ranges [-90, 90] and [-180, 180], respectively.
  """
  lat = None
  lon = None

  def __init__(self, lat, lon=None):
    if lon is None:

      try:
        split = lat.split(',')
        lat, lon = split
      except (AttributeError, ValueError):
        raise datastore_errors.BadValueError(
          'Expected a "lat,long" formatted string; received %s (a %s).' %
          (lat, typename(lat)))

    try:
      lat = float(lat)
      lon = float(lon)
      if abs(lat) > 90:
        raise datastore_errors.BadValueError(
          'Latitude must be between -90 and 90; received %f' % lat)
      if abs(lon) > 180:
        raise datastore_errors.BadValueError(
          'Longitude must be between -180 and 180; received %f' % lon)
    except (TypeError, ValueError):

      raise datastore_errors.BadValueError(
        'Expected floats for lat and long; received %s (a %s) and %s (a %s).' %
        (lat, typename(lat), lon, typename(lon)))

    self.lat = lat
    self.lon = lon

  def __cmp__(self, other):
    if not isinstance(other, GeoPt):
      try:
        other = GeoPt(other)
      except datastore_errors.BadValueError:
        return NotImplemented


    lat_cmp = cmp(self.lat, other.lat)
    if lat_cmp != 0:
      return lat_cmp
    else:
      return cmp(self.lon, other.lon)

  def __hash__(self):
    """Returns an integer hash of this point.

    Implements Python's hash protocol so that GeoPts may be used in sets and
    as dictionary keys.

    Returns:
      int
    """
    return hash((self.lat, self.lon))

  def __repr__(self):
    """Returns an eval()able string representation of this GeoPt.

    The returned string is of the form 'datastore_types.GeoPt([lat], [lon])'.

    Returns:
      string
    """
    return 'datastore_types.GeoPt(%r, %r)' % (self.lat, self.lon)

  def __unicode__(self):
    return u'%s,%s' % (unicode(self.lat), unicode(self.lon))

  __str__ = __unicode__

  def ToXml(self):
    return u'<georss:point>%s %s</georss:point>' % (unicode(self.lat),
                                                    unicode(self.lon))


class IM(object):
  """An instant messaging handle. Includes both an address and its protocol.
  The protocol value is either a standard IM scheme or a URL identifying the
  IM network for the protocol. Possible values include:

    Value                           Description
    sip                             SIP/SIMPLE
    unknown                         Unknown or unspecified
    xmpp                            XMPP/Jabber
    http://aim.com/                 AIM
    http://icq.com/                 ICQ
    http://talk.google.com/         Google Talk
    http://messenger.msn.com/       MSN Messenger
    http://messenger.yahoo.com/     Yahoo Messenger
    http://sametime.com/            Lotus Sametime
    http://gadu-gadu.pl/            Gadu-Gadu

  This is the gd:im element. In XML output, the address and protocol are
  provided as the address and protocol attributes, respectively. See:
  http://code.google.com/apis/gdata/common-elements.html#gdIm

  Serializes to '<protocol> <address>'. Raises BadValueError if tag is not a
  standard IM scheme or a URL.
  """
  PROTOCOLS = [ 'sip', 'unknown', 'xmpp' ]

  protocol = None
  address = None

  def __init__(self, protocol, address=None):
    if address is None:

      try:
        split = protocol.split(' ', 1)
        protocol, address = split
      except (AttributeError, ValueError):
        raise datastore_errors.BadValueError(
          'Expected string of format "protocol address"; received %s' %
          (protocol,))

    ValidateString(address, 'address')
    if protocol not in self.PROTOCOLS:

      Link(protocol)

    self.address = address
    self.protocol = protocol

  def __cmp__(self, other):
    if not isinstance(other, IM):
      try:
        other = IM(other)
      except datastore_errors.BadValueError:
        return NotImplemented











    return cmp((self.address, self.protocol),
               (other.address, other.protocol))

  def __repr__(self):
    """Returns an eval()able string representation of this IM.

    The returned string is of the form:

      datastore_types.IM('address', 'protocol')

    Returns:
      string
    """
    return 'datastore_types.IM(%r, %r)' % (self.protocol, self.address)

  def __unicode__(self):
    return u'%s %s' % (self.protocol, self.address)

  __str__ = __unicode__

  def ToXml(self):
    return (u'<gd:im protocol=%s address=%s />' %
            (saxutils.quoteattr(self.protocol),
             saxutils.quoteattr(self.address)))

  def __len__(self):
    return len(unicode(self))


class PhoneNumber(unicode):
  """A human-readable phone number or address.

  No validation is performed. Phone numbers have many different formats -
  local, long distance, domestic, international, internal extension, TTY,
  VOIP, SMS, and alternative networks like Skype, XFire and Roger Wilco. They
  all have their own numbering and addressing formats.

  This is the gd:phoneNumber element. In XML output, the phone number is
  provided as the text of the element. See:
  http://code.google.com/apis/gdata/common-elements.html#gdPhoneNumber

  Raises BadValueError if phone is not a string or subtype.
  """
  def __init__(self, phone):
    super(PhoneNumber, self).__init__()
    ValidateString(phone, 'phone')

  def ToXml(self):
    return u'<gd:phoneNumber>%s</gd:phoneNumber>' % saxutils.escape(self)


class PostalAddress(unicode):
  """A human-readable mailing address. Again, mailing address formats vary
  widely, so no validation is performed.

  This is the gd:postalAddress element. In XML output, the address is provided
  as the text of the element. See:
  http://code.google.com/apis/gdata/common-elements.html#gdPostalAddress

  Raises BadValueError if address is not a string or subtype.
  """
  def __init__(self, address):
    super(PostalAddress, self).__init__()
    ValidateString(address, 'address')

  def ToXml(self):
    return u'<gd:postalAddress>%s</gd:postalAddress>' % saxutils.escape(self)


class Rating(long):
  """A user-provided integer rating for a piece of content. Normalized to a
  0-100 scale.

  This is the gd:rating element. In XML output, the address is provided
  as the text of the element. See:
  http://code.google.com/apis/gdata/common-elements.html#gdRating

  Serializes to the decimal string representation of the rating. Raises
  BadValueError if the rating is not an integer in the range [0, 100].
  """
  MIN = 0
  MAX = 100

  def __init__(self, rating):
    super(Rating, self).__init__()
    if isinstance(rating, float) or isinstance(rating, complex):

      raise datastore_errors.BadValueError(
        'Expected int or long; received %s (a %s).' %
        (rating, typename(rating)))

    try:
      if long(rating) < Rating.MIN or long(rating) > Rating.MAX:
        raise datastore_errors.BadValueError()
    except ValueError:

      raise datastore_errors.BadValueError(
        'Expected int or long; received %s (a %s).' %
        (rating, typename(rating)))

  def ToXml(self):
    return (u'<gd:rating value="%d" min="%d" max="%d" />' %
            (self, Rating.MIN, Rating.MAX))


class Text(unicode):
  """A long string type.

  Strings of any length can be stored in the datastore using this
  type. It behaves identically to the Python unicode type, except for
  the constructor, which only accepts str and unicode arguments.
  """

  def __new__(cls, arg=None, encoding=None):
    """Constructor.

    We only accept unicode and str instances, the latter with encoding.

    Args:
      arg: optional unicode or str instance; default u''
      encoding: optional encoding; disallowed when isinstance(arg, unicode),
                defaults to 'ascii' when isinstance(arg, str);
    """
    if arg is None:
      arg = u''
    if isinstance(arg, unicode):
      if encoding is not None:
        raise TypeError('Text() with a unicode argument '
                        'should not specify an encoding')
      return super(Text, cls).__new__(cls, arg)

    if isinstance(arg, str):
      if encoding is None:
        encoding = 'ascii'
      return super(Text, cls).__new__(cls, arg, encoding)

    raise TypeError('Text() argument should be str or unicode, not %s' %
                    type(arg).__name__)

class _BaseByteType(str):
  """A base class for datastore types that are encoded as bytes.

  This behaves identically to the Python str type, except for the
  constructor, which only accepts str arguments.
  """

  def __new__(cls, arg=None):
    """Constructor.

    We only accept str instances.

    Args:
      arg: optional str instance (default '')
    """
    if arg is None:
      arg = ''
    if isinstance(arg, str):
      return super(_BaseByteType, cls).__new__(cls, arg)

    raise TypeError('%s() argument should be str instance, not %s' %
                    (cls.__name__, type(arg).__name__))

  def ToXml(self):
    """Output bytes as XML.

    Returns:
      Base64 encoded version of itself for safe insertion in to an XML document.
    """
    encoded = base64.urlsafe_b64encode(self)
    return saxutils.escape(encoded)


class Blob(_BaseByteType):
  """A blob type, appropriate for storing binary data of any length.

  This behaves identically to the Python str type, except for the
  constructor, which only accepts str arguments.
  """
  pass


class EmbeddedEntity(_BaseByteType):
  """A proto encoded EntityProto.

  This behaves identically to Blob, except for the
  constructor, which accepts a str or EntityProto argument.

  Can be decoded using datastore.Entity.FromProto(), db.model_from_protobuf() or
  ndb.LocalStructuredProperty.
  """

  def __new__(cls, arg=None):
    """Constructor.

    Args:
      arg: optional str or EntityProto instance (default '')
    """
    if isinstance(arg, entity_pb.EntityProto):
      arg = arg.SerializePartialToString()
    return super(EmbeddedEntity, cls).__new__(cls, arg)


class ByteString(_BaseByteType):
  """A byte-string type, appropriate for storing short amounts of indexed data.

  This behaves identically to Blob, except it's used only for short, indexed
  byte strings.
  """
  pass


class BlobKey(object):
  """Key used to identify a blob in Blobstore.

  This object wraps a string that gets used internally by the Blobstore API
  to identify application blobs.  The BlobKey corresponds to the entity name
  of the underlying BlobReference entity.

  This class is exposed in the API in both google.appengine.ext.db and
  google.appengine.ext.blobstore.
  """

  def __init__(self, blob_key):
    """Constructor.

    Used to convert a string to a BlobKey.  Normally used internally by
    Blobstore API.

    Args:
      blob_key:  Key name of BlobReference that this key belongs to.
    """
    ValidateString(blob_key, 'blob-key')
    self.__blob_key = blob_key

  def __str__(self):
    """Convert to string."""
    return self.__blob_key

  def __repr__(self):
    """Returns an eval()able string representation of this key.

    Returns a Python string of the form 'datastore_types.BlobKey(...)'
    that can be used to recreate this key.

    Returns:
      string
    """
    return 'datastore_types.%s(%r)' % (type(self).__name__, self.__blob_key)

  def __cmp__(self, other):


    if type(other) is type(self):
      return cmp(str(self), str(other))
    elif isinstance(other, basestring):
      return cmp(self.__blob_key, other)
    else:
      return NotImplemented

  def __hash__(self):
    return hash(self.__blob_key)

  def ToXml(self):
    return str(self)



_PROPERTY_MEANINGS = {



  Blob:              entity_pb.Property.BLOB,
  EmbeddedEntity:    entity_pb.Property.ENTITY_PROTO,
  ByteString:        entity_pb.Property.BYTESTRING,
  Text:              entity_pb.Property.TEXT,
  datetime.datetime: entity_pb.Property.GD_WHEN,
  datetime.date:     entity_pb.Property.GD_WHEN,
  datetime.time:     entity_pb.Property.GD_WHEN,
  _OverflowDateTime: entity_pb.Property.GD_WHEN,
  Category:          entity_pb.Property.ATOM_CATEGORY,
  Link:              entity_pb.Property.ATOM_LINK,
  Email:             entity_pb.Property.GD_EMAIL,
  GeoPt:             entity_pb.Property.GEORSS_POINT,
  IM:                entity_pb.Property.GD_IM,
  PhoneNumber:       entity_pb.Property.GD_PHONENUMBER,
  PostalAddress:     entity_pb.Property.GD_POSTALADDRESS,
  Rating:            entity_pb.Property.GD_RATING,
  BlobKey:           entity_pb.Property.BLOBKEY,
}


_PROPERTY_TYPES = frozenset([
  Blob,
  EmbeddedEntity,
  ByteString,
  bool,
  Category,
  datetime.datetime,
  _OverflowDateTime,
  Email,
  float,
  GeoPt,
  IM,
  int,
  Key,
  Link,
  long,
  PhoneNumber,
  PostalAddress,
  Rating,
  str,
  Text,
  type(None),
  unicode,
  users.User,
  BlobKey,
])




_RAW_PROPERTY_TYPES = (Blob, Text, EmbeddedEntity)
_RAW_PROPERTY_MEANINGS = (entity_pb.Property.BLOB, entity_pb.Property.TEXT,
                          entity_pb.Property.ENTITY_PROTO)


def ValidatePropertyInteger(name, value):
  """Raises an exception if the supplied integer is invalid.

  Args:
    name: Name of the property this is for.
    value: Integer value.

  Raises:
    OverflowError if the value does not fit within a signed int64.
  """
  if not (-0x8000000000000000 <= value <= 0x7fffffffffffffff):
    raise OverflowError('%d is out of bounds for int64' % value)


def ValidateStringLength(name, value, max_len):
  """Raises an exception if the supplied string is too long.

  Args:
    name: Name of the property this is for.
    value: String value.
    max_len: Maximum length the string may be.

  Raises:
    OverflowError if the value is larger than the maximum length.
  """
  if len(value) > max_len:
    raise datastore_errors.BadValueError(
      'Property %s is %d bytes long; it must be %d or less. '
      'Consider Text instead, which can store strings of any length.' %
      (name, len(value), max_len))


def ValidatePropertyString(name, value):
  """Validates the length of an indexed string property.

  Args:
    name: Name of the property this is for.
    value: String value.
  """
  ValidateStringLength(name, value, max_len=_MAX_STRING_LENGTH)


def ValidatePropertyLink(name, value):
  """Validates the length of an indexed Link property.

  Args:
    name: Name of the property this is for.
    value: String value.
  """
  ValidateStringLength(name, value, max_len=_MAX_LINK_PROPERTY_LENGTH)


def ValidatePropertyNothing(name, value):
  """No-op validation function.

  Args:
    name: Name of the property this is for.
    value: Not used.
  """
  pass


def ValidatePropertyKey(name, value):
  """Raises an exception if the supplied datastore.Key instance is invalid.

  Args:
    name: Name of the property this is for.
    value: A datastore.Key instance.

  Raises:
    datastore_errors.BadValueError if the value is invalid.
  """
  if not value.has_id_or_name():
    raise datastore_errors.BadValueError(
        'Incomplete key found for reference property %s.' % name)







_VALIDATE_PROPERTY_VALUES = {
  Blob: ValidatePropertyNothing,
  EmbeddedEntity: ValidatePropertyNothing,
  ByteString: ValidatePropertyNothing,
  bool: ValidatePropertyNothing,
  Category: ValidatePropertyNothing,
  datetime.datetime: ValidatePropertyNothing,
  _OverflowDateTime: ValidatePropertyInteger,
  Email: ValidatePropertyNothing,
  float: ValidatePropertyNothing,
  GeoPt: ValidatePropertyNothing,
  IM: ValidatePropertyNothing,
  int: ValidatePropertyInteger,
  Key: ValidatePropertyKey,
  Link: ValidatePropertyNothing,
  long: ValidatePropertyInteger,
  PhoneNumber: ValidatePropertyNothing,
  PostalAddress: ValidatePropertyNothing,
  Rating: ValidatePropertyInteger,
  str: ValidatePropertyNothing,
  Text: ValidatePropertyNothing,
  type(None): ValidatePropertyNothing,
  unicode: ValidatePropertyNothing,
  users.User: ValidatePropertyNothing,
  BlobKey: ValidatePropertyNothing,
}

_PROPERTY_TYPE_TO_INDEX_VALUE_TYPE = {
  basestring: str,
  Blob: str,
  EmbeddedEntity: str,
  ByteString: str,
  bool: bool,
  Category: str,
  datetime.datetime: long,
  datetime.date: long,
  datetime.time: long,
  _OverflowDateTime: long,
  Email: str,
  float: float,
  GeoPt: GeoPt,
  IM: str,
  int: long,
  Key: Key,
  Link: str,
  long: long,
  PhoneNumber: str,
  PostalAddress: str,
  Rating: long,
  str: str,
  Text: str,
  type(None): type(None),
  unicode: str,
  users.User: users.User,
  BlobKey: str,
}


assert set(_VALIDATE_PROPERTY_VALUES.iterkeys()) == _PROPERTY_TYPES


def ValidateProperty(name, values, read_only=False):
  """Helper function for validating property values.

  Args:
    name: Name of the property this is for.
    value: Value for the property as a Python native type.
    read_only: deprecated

  Raises:
    BadPropertyError if the property name is invalid. BadValueError if the
    property did not validate correctly or the value was an empty list. Other
    exception types (like OverflowError) if the property value does not meet
    type-specific criteria.
  """
  ValidateString(name, 'property name', datastore_errors.BadPropertyError)

  values_type = type(values)


  if values_type is tuple:
    raise datastore_errors.BadValueError(
        'May not use tuple property value; property %s is %s.' %
        (name, repr(values)))


  if values_type is not list:
    values = [values]


  if not values:
    raise datastore_errors.BadValueError(
        'May not use the empty list as a property value; property %s is %s.' %
        (name, repr(values)))



  try:
    for v in values:
      prop_validator = _VALIDATE_PROPERTY_VALUES.get(v.__class__)
      if prop_validator is None:
        raise datastore_errors.BadValueError(
          'Unsupported type for property %s: %s' % (name, v.__class__))
      prop_validator(name, v)

  except (KeyError, ValueError, TypeError, IndexError, AttributeError), msg:
    raise datastore_errors.BadValueError(
      'Error type checking values for property %s: %s' % (name, msg))





ValidateReadProperty = ValidateProperty



def PackBlob(name, value, pbvalue):
  """Packs a Blob property into a entity_pb.PropertyValue.

  Args:
    name: The name of the property as a string.
    value: A Blob instance.
    pbvalue: The entity_pb.PropertyValue to pack this value into.
  """
  pbvalue.set_stringvalue(value)


def PackString(name, value, pbvalue):
  """Packs a string-typed property into a entity_pb.PropertyValue.

  Args:
    name: The name of the property as a string.
    value: A string, unicode, or string-like value instance.
    pbvalue: The entity_pb.PropertyValue to pack this value into.
  """
  pbvalue.set_stringvalue(unicode(value).encode('utf-8'))


def PackDatetime(name, value, pbvalue):
  """Packs a datetime-typed property into a entity_pb.PropertyValue.

  Args:
    name: The name of the property as a string.
    value: A datetime.datetime instance.
    pbvalue: The entity_pb.PropertyValue to pack this value into.
  """
  pbvalue.set_int64value(DatetimeToTimestamp(value))


def DatetimeToTimestamp(value):
  """Converts a datetime.datetime to microseconds since the epoch, as a float.
  Args:
    value: datetime.datetime

  Returns: value as a long
  """
  if value.tzinfo:

    value = value.astimezone(UTC)
  return long(calendar.timegm(value.timetuple()) * 1000000L) + value.microsecond


def PackGeoPt(name, value, pbvalue):
  """Packs a GeoPt property into a entity_pb.PropertyValue.

  Args:
    name: The name of the property as a string.
    value: A GeoPt instance.
    pbvalue: The entity_pb.PropertyValue to pack this value into.
  """
  pbvalue.mutable_pointvalue().set_x(value.lat)
  pbvalue.mutable_pointvalue().set_y(value.lon)


def PackUser(name, value, pbvalue):
  """Packs a User property into a entity_pb.PropertyValue.

  Args:
    name: The name of the property as a string.
    value: A users.User instance.
    pbvalue: The entity_pb.PropertyValue to pack this value into.
  """
  pbvalue.mutable_uservalue().set_email(value.email().encode('utf-8'))
  pbvalue.mutable_uservalue().set_auth_domain(
      value.auth_domain().encode('utf-8'))
  pbvalue.mutable_uservalue().set_gaiaid(0)




  if value.user_id() is not None:
    pbvalue.mutable_uservalue().set_obfuscated_gaiaid(
        value.user_id().encode('utf-8'))

  if value.federated_identity() is not None:
    pbvalue.mutable_uservalue().set_federated_identity(
        value.federated_identity().encode('utf-8'))

  if value.federated_provider() is not None:
    pbvalue.mutable_uservalue().set_federated_provider(
        value.federated_provider().encode('utf-8'))


def PackKey(name, value, pbvalue):
  """Packs a reference property into a entity_pb.PropertyValue.

  Args:
    name: The name of the property as a string.
    value: A Key instance.
    pbvalue: The entity_pb.PropertyValue to pack this value into.
  """
  ref = value._Key__reference
  pbvalue.mutable_referencevalue().set_app(ref.app())
  SetNamespace(pbvalue.mutable_referencevalue(), ref.name_space())
  for elem in ref.path().element_list():
    pbvalue.mutable_referencevalue().add_pathelement().CopyFrom(elem)


def PackBool(name, value, pbvalue):
  """Packs a boolean property into a entity_pb.PropertyValue.

  Args:
    name: The name of the property as a string.
    value: A boolean instance.
    pbvalue: The entity_pb.PropertyValue to pack this value into.
  """
  pbvalue.set_booleanvalue(value)


def PackInteger(name, value, pbvalue):
  """Packs an integer property into a entity_pb.PropertyValue.

  Args:
    name: The name of the property as a string.
    value: An int or long instance.
    pbvalue: The entity_pb.PropertyValue to pack this value into.
  """
  pbvalue.set_int64value(value)


def PackFloat(name, value, pbvalue):
  """Packs a float property into a entity_pb.PropertyValue.

  Args:
    name: The name of the property as a string.
    value: A float instance.
    pbvalue: The entity_pb.PropertyValue to pack this value into.
  """
  pbvalue.set_doublevalue(value)







_PACK_PROPERTY_VALUES = {
  Blob: PackBlob,
  EmbeddedEntity: PackBlob,
  ByteString: PackBlob,
  bool: PackBool,
  Category: PackString,
  datetime.datetime: PackDatetime,
  _OverflowDateTime: PackInteger,
  Email: PackString,
  float: PackFloat,
  GeoPt: PackGeoPt,
  IM: PackString,
  int: PackInteger,
  Key: PackKey,
  Link: PackString,
  long: PackInteger,
  PhoneNumber: PackString,
  PostalAddress: PackString,
  Rating: PackInteger,
  str: PackString,
  Text: PackString,
  type(None): lambda name, value, pbvalue: None,
  unicode: PackString,
  users.User: PackUser,
  BlobKey: PackString,
}


assert set(_PACK_PROPERTY_VALUES.iterkeys()) == _PROPERTY_TYPES


def ToPropertyPb(name, values):
  """Creates type-specific entity_pb.PropertyValues.

  Determines the type and meaning of the PropertyValue based on the Python
  type of the input value(s).

  NOTE: This function does not validate anything!

  Args:
    name: string or unicode; the property name
    values: The values for this property, either a single one or a list of them.
      All values must be a supported type. Lists of values must all be of the
      same type.

  Returns:
    A list of entity_pb.Property instances.
  """
  encoded_name = name.encode('utf-8')

  values_type = type(values)
  if values_type is list:
    multiple = True
  else:
    multiple = False
    values = [values]

  pbs = []
  for v in values:
    pb = entity_pb.Property()
    pb.set_name(encoded_name)
    pb.set_multiple(multiple)

    meaning = _PROPERTY_MEANINGS.get(v.__class__)
    if meaning is not None:
      pb.set_meaning(meaning)

    pack_prop = _PACK_PROPERTY_VALUES[v.__class__]
    pbvalue = pack_prop(name, v, pb.mutable_value())
    pbs.append(pb)

  if multiple:
    return pbs
  else:
    return pbs[0]


def FromReferenceProperty(value):
  """Converts a reference PropertyValue to a Key.

  Args:
    value: entity_pb.PropertyValue

  Returns:
    Key

  Raises:
    BadValueError if the value is not a PropertyValue.
  """
  assert isinstance(value, entity_pb.PropertyValue)
  assert value.has_referencevalue()
  ref = value.referencevalue()

  key = Key()
  key_ref = key._Key__reference
  key_ref.set_app(ref.app())
  SetNamespace(key_ref, ref.name_space())

  for pathelem in ref.pathelement_list():
    key_ref.mutable_path().add_element().CopyFrom(pathelem)

  return key









_PROPERTY_CONVERSIONS = {
  entity_pb.Property.GD_WHEN:           _When,
  entity_pb.Property.ATOM_CATEGORY:     Category,
  entity_pb.Property.ATOM_LINK:         Link,
  entity_pb.Property.GD_EMAIL:          Email,
  entity_pb.Property.GD_IM:             IM,
  entity_pb.Property.GD_PHONENUMBER:    PhoneNumber,
  entity_pb.Property.GD_POSTALADDRESS:  PostalAddress,
  entity_pb.Property.GD_RATING:         Rating,
  entity_pb.Property.BLOB:              Blob,
  entity_pb.Property.ENTITY_PROTO:      EmbeddedEntity,
  entity_pb.Property.BYTESTRING:        ByteString,
  entity_pb.Property.TEXT:              Text,
  entity_pb.Property.BLOBKEY:           BlobKey,
}


_NON_UTF8_MEANINGS = frozenset((entity_pb.Property.BLOB,
                                entity_pb.Property.ENTITY_PROTO,
                                entity_pb.Property.BYTESTRING,
                                entity_pb.Property.INDEX_VALUE))


def FromPropertyPb(pb):
  """Converts a property PB to a python value.

  Args:
    pb: entity_pb.Property

  Returns:
    # return type is determined by the type of the argument
    string, int, bool, double, users.User, or one of the atom or gd types
  """



  pbval = pb.value()
  meaning = pb.meaning()

  if pbval.has_stringvalue():
    value = pbval.stringvalue()
    if not pb.has_meaning() or meaning not in _NON_UTF8_MEANINGS:
      value = unicode(value, 'utf-8')
  elif pbval.has_int64value():


    value = long(pbval.int64value())
  elif pbval.has_booleanvalue():


    value = bool(pbval.booleanvalue())
  elif pbval.has_doublevalue():
    value = pbval.doublevalue()
  elif pbval.has_referencevalue():
    value = FromReferenceProperty(pbval)
  elif pbval.has_pointvalue():
    value = GeoPt(pbval.pointvalue().x(), pbval.pointvalue().y())
  elif pbval.has_uservalue():
    email = unicode(pbval.uservalue().email(), 'utf-8')
    auth_domain = unicode(pbval.uservalue().auth_domain(), 'utf-8')
    obfuscated_gaiaid = pbval.uservalue().obfuscated_gaiaid().decode('utf-8')
    obfuscated_gaiaid = unicode(pbval.uservalue().obfuscated_gaiaid(), 'utf-8')

    federated_identity = None
    if pbval.uservalue().has_federated_identity():
      federated_identity = unicode(pbval.uservalue().federated_identity(),
                                   'utf-8')



    value = users.User(email=email,
                       _auth_domain=auth_domain,
                       _user_id=obfuscated_gaiaid,
                       federated_identity=federated_identity,
                       _strict_mode=False)
  else:
    value = None

  try:
    if pb.has_meaning() and meaning in _PROPERTY_CONVERSIONS:
      conversion = _PROPERTY_CONVERSIONS[meaning]
      value = conversion(value)
  except (KeyError, ValueError, IndexError, TypeError, AttributeError), msg:
    raise datastore_errors.BadValueError(
      'Error converting pb: %s\nException was: %s' % (pb, msg))

  return value


def RestoreFromIndexValue(index_value, data_type):
  """Restores a index value to the correct datastore type.

  Projection queries return property values direclty from a datastore index.
  These values are the native datastore values, one of str, bool, long, float,
  GeoPt, Key or User. This function restores the original value when the the
  original type is known.

  This function returns the value type returned when decoding a normal entity,
  not necessarily of type data_type. For example, data_type=int returns a
  long instance.

  Args:
    index_value: The value returned by FromPropertyPb for the projected
      property.
    data_type: The type of the value originally given to ToPropertyPb

  Returns:
    The restored property value.

  Raises:
    datastore_errors.BadValueError if the value cannot be restored.
  """
  raw_type = _PROPERTY_TYPE_TO_INDEX_VALUE_TYPE.get(data_type)
  if raw_type is None:
    raise datastore_errors.BadValueError(
        'Unsupported data type (%r)' % data_type)

  if index_value is None:
    return index_value



  if not isinstance(index_value, raw_type):
    raise datastore_errors.BadValueError(
        'Unsupported converstion. Expected %r got %r' %
        (type(index_value), raw_type))

  meaning = _PROPERTY_MEANINGS.get(data_type)


  if isinstance(index_value, str) and meaning not in _NON_UTF8_MEANINGS:
    index_value = unicode(index_value, 'utf-8')


  conv = _PROPERTY_CONVERSIONS.get(meaning)
  if not conv:
    return index_value

  try:
    value = conv(index_value)
  except (KeyError, ValueError, IndexError, TypeError, AttributeError), msg:
    raise datastore_errors.BadValueError(
      'Error converting value: %r\nException was: %s' % (index_value, msg))
  return value


def PropertyTypeName(value):
  """Returns the name of the type of the given property value, as a string.

  Raises BadValueError if the value is not a valid property type.

  Args:
    value: any valid property value

  Returns:
    string
  """
  if value.__class__ in _PROPERTY_MEANINGS:
    meaning = _PROPERTY_MEANINGS[value.__class__]
    name = entity_pb.Property._Meaning_NAMES[meaning]
    return name.lower().replace('_', ':')
  elif isinstance(value, basestring):
    return 'string'
  elif isinstance(value, users.User):
    return 'user'
  elif isinstance(value, long):
    return 'int'
  elif value is None:
    return 'null'
  else:
    return typename(value).lower()


_PROPERTY_TYPE_STRINGS = {
    'string':           unicode,
    'bool':             bool,
    'int':              long,
    'null':             type(None),
    'float':            float,
    'key':              Key,
    'blob':             Blob,
    'entity:proto':     EmbeddedEntity,
    'bytestring':       ByteString,
    'text':             Text,
    'user':             users.User,
    'atom:category':    Category,
    'atom:link':        Link,
    'gd:email':         Email,
    'gd:when':          datetime.datetime,
    'georss:point':     GeoPt,
    'gd:im':            IM,
    'gd:phonenumber':   PhoneNumber,
    'gd:postaladdress': PostalAddress,
    'gd:rating':        Rating,
    'blobkey':          BlobKey,
    }


def FromPropertyTypeName(type_name):
  """Returns the python type given a type name.

  Args:
    type_name: A string representation of a datastore type name.

  Returns:
    A python type.
  """
  return _PROPERTY_TYPE_STRINGS[type_name]


def PropertyValueFromString(type_,
                            value_string,
                            _auth_domain=None):
  """Returns an instance of a property value given a type and string value.

  The reverse of this method is just str() and type() of the python value.

  Note that this does *not* support non-UTC offsets in ISO 8601-formatted
  datetime strings, e.g. the -08:00 suffix in '2002-12-25 00:00:00-08:00'.
  It only supports -00:00 and +00:00 suffixes, which are UTC.

  Args:
    type_: A python class.
    value_string: A string representation of the value of the property.

  Returns:
    An instance of 'type'.

  Raises:
    ValueError if type_ is datetime and value_string has a timezone offset.
  """
  if type_ == datetime.datetime:
    value_string = value_string.strip()

    if value_string[-6] in ('+', '-'):
      if value_string[-5:] == '00:00':
        value_string = value_string[:-6]
      else:

        raise ValueError('Non-UTC offsets in datetimes are not supported.')


    split = value_string.split('.')
    iso_date = split[0]
    microseconds = 0
    if len(split) > 1:
      microseconds = int(split[1])



    time_struct = time.strptime(iso_date, '%Y-%m-%d %H:%M:%S')[0:6]
    value = datetime.datetime(*(time_struct + (microseconds,)))
    return value
  elif type_ == Rating:

    return Rating(int(value_string))
  elif type_ == bool:
    return value_string == 'True'
  elif type_ == users.User:
    return users.User(value_string, _auth_domain)
  elif type_ == type(None):
    return None
  return type_(value_string)


def ReferenceToKeyValue(key):
  """Converts a key into a comparable hashable "key" value.

  Args:
    key: The entity_pb.Reference or entity_v4_pb.Key from which to construct
        the key value.

  Returns:
    A comparable and hashable representation of the given key that is
    compatible with one derived from a key property value.
  """
  if isinstance(key, entity_v4_pb.Key):
    v4_key = key
    key = entity_pb.Reference()
    datastore_pbs.get_entity_converter().v4_to_v3_reference(v4_key, key)

  if isinstance(key, entity_pb.Reference):
    element_list = key.path().element_list()
  elif isinstance(key, entity_pb.PropertyValue_ReferenceValue):
    element_list = key.pathelement_list()
  else:
    raise datastore_errors.BadArgumentError(
        "key arg expected to be entity_pb.Reference or entity_v4.Key (%r)"
        % (key,))

  result = [entity_pb.PropertyValue.kReferenceValueGroup,
            key.app(), key.name_space()]
  for element in element_list:
    result.append(element.type())
    if element.has_name():
      result.append(element.name())
    else:
      result.append(element.id())
  return tuple(result)


def PropertyValueToKeyValue(prop_value):
  """Converts a entity_pb.PropertyValue into a comparable hashable "key" value.

  The values produces by this function mimic the native ording of the datastore
  and uniquely identify the given PropertyValue.

  Args:
    prop_value: The entity_pb.PropertyValue from which to construct the
      key value.

  Returns:
    A comparable and hashable representation of the given property value.
  """
  if not isinstance(prop_value, entity_pb.PropertyValue):
    raise datastore_errors.BadArgumentError(
        'prop_value arg expected to be entity_pb.PropertyValue (%r)' %
        (prop_value,))



  if prop_value.has_stringvalue():
    return (entity_pb.PropertyValue.kstringValue, prop_value.stringvalue())
  if prop_value.has_int64value():
    return (entity_pb.PropertyValue.kint64Value, prop_value.int64value())
  if prop_value.has_booleanvalue():
    return (entity_pb.PropertyValue.kbooleanValue, prop_value.booleanvalue())
  if prop_value.has_doublevalue():

    encoder = sortable_pb_encoder.Encoder()
    encoder.putDouble(prop_value.doublevalue())
    return (entity_pb.PropertyValue.kdoubleValue, tuple(encoder.buf))
  if prop_value.has_pointvalue():
    return (entity_pb.PropertyValue.kPointValueGroup,
            prop_value.pointvalue().x(), prop_value.pointvalue().y())
  if prop_value.has_referencevalue():
    return ReferenceToKeyValue(prop_value.referencevalue())
  if prop_value.has_uservalue():
    result = []
    uservalue = prop_value.uservalue()
    if uservalue.has_email():
      result.append((entity_pb.PropertyValue.kUserValueemail,
                     uservalue.email()))
    if uservalue.has_auth_domain():
      result.append((entity_pb.PropertyValue.kUserValueauth_domain,
                     uservalue.auth_domain()))
    if uservalue.has_nickname():
      result.append((entity_pb.PropertyValue.kUserValuenickname,
                     uservalue.nickname()))
    if uservalue.has_gaiaid():
      result.append((entity_pb.PropertyValue.kUserValuegaiaid,
                     uservalue.gaiaid()))
    if uservalue.has_obfuscated_gaiaid():
      result.append((entity_pb.PropertyValue.kUserValueobfuscated_gaiaid,
                     uservalue.obfuscated_gaiaid()))
    if uservalue.has_federated_identity():
      result.append((entity_pb.PropertyValue.kUserValuefederated_identity,
                     uservalue.federated_identity()))
    if uservalue.has_federated_provider():
      result.append((entity_pb.PropertyValue.kUserValuefederated_provider,
                     uservalue.federated_provider()))
    result.sort()
    return (entity_pb.PropertyValue.kUserValueGroup, tuple(result))
  return ()


def GetPropertyValueTag(value_pb):
  """Returns the tag constant associated with the given entity_pb.PropertyValue.
  """
  if value_pb.has_booleanvalue():
    return entity_pb.PropertyValue.kbooleanValue
  elif value_pb.has_doublevalue():
    return entity_pb.PropertyValue.kdoubleValue
  elif value_pb.has_int64value():
    return entity_pb.PropertyValue.kint64Value
  elif value_pb.has_pointvalue():
    return entity_pb.PropertyValue.kPointValueGroup
  elif value_pb.has_referencevalue():
    return entity_pb.PropertyValue.kReferenceValueGroup
  elif value_pb.has_stringvalue():
    return entity_pb.PropertyValue.kstringValue
  elif value_pb.has_uservalue():
    return entity_pb.PropertyValue.kUserValueGroup
  else:
    return 0
