# Path: ndb/msgprop.py
# class MessageProperty(model.StructuredProperty):
#   """Messages are represented in Cloud Datastore as structured properties.
# 
#   By default, the structured property has a single subproperty
#   containing the serialized message.  This property is named 'blob_'
#   in Python but __<protocol>__ in the Datastore, where <protocol> is
#   the value of the protocol argument (default 'protobuf').
#   """
# 
#   _message_type = None
#   _indexed_fields = ()
#   _protocol = _default_protocol
#   _protocol_impl = None
# 
#   # *Replace* first positional argument with _message_type, since the
#   # _modelclass attribute is synthetic.
#   _attributes = (['_message_type'] + model.StructuredProperty._attributes[1:] +
#                  ['_indexed_fields', '_protocol'])
# 
#   @utils.positional(1 + model.StructuredProperty._positional)
#   def __init__(self, message_type, name=None,
#                indexed_fields=None, protocol=None, **kwds):
#     """Constructor.
# 
#     Args:
#       message_tyoe: A subclass of protorpc.messages.Message.
#       name: Optional datastore name (defaults to the property name).
#       indexed_fields: Optional list of dotted and undotted field names.
#       protocol: Optional protocol name default 'protobuf'.
# 
#     Additional keywords arguments specify the same options as
#     supported by StructuredProperty, except 'indexed'.
#     """
#     if not (isinstance(message_type, type) and
#             issubclass(message_type, messages.Message)):
#       raise TypeError('MessageProperty argument must be a Message subclass')
#     self._message_type = message_type
#     if indexed_fields is not None:
#       # TODO: Check they are all strings naming fields.
#       self._indexed_fields = tuple(indexed_fields)
#     # NOTE: Otherwise the class default i.e. (), prevails.
#     if protocol is None:
#       protocol = _default_protocol
#     self._protocol = protocol
#     self._protocol_impl = _protocols_registry.lookup_by_name(protocol)
#     blob_prop = model.BlobProperty('__%s__' % self._protocol)
#     # TODO: Solve this without reserving 'blob_'.
#     message_class = _make_model_class(message_type, self._indexed_fields,
#                                       blob_=blob_prop)
#     super(MessageProperty, self).__init__(message_class, name, **kwds)
# 
#   def _validate(self, msg):
#     """Validate an Enum value.
# 
#     Raises:
#       TypeError if the value is not an instance of self._message_type.
#     """
#     if not isinstance(msg, self._message_type):
#       raise TypeError('Expected a %s instance for %s property',
#                       self._message_type.__name__,
#                       self._code_name or self._name)
# 
#   def _to_base_type(self, msg):
#     """Convert a Message value to a Model instance (entity)."""
#     ent = _message_to_entity(msg, self._modelclass)
#     ent.blob_ = self._protocol_impl.encode_message(msg)
#     return ent
# 
#   def _from_base_type(self, ent):
#     """Convert a Model instance (entity) to a Message value."""
#     if ent._projection:
#       # Projection query result.  Reconstitute the message from the fields.
#       return _projected_entity_to_message(ent, self._message_type)
# 
#     blob = ent.blob_
#     if blob is not None:
#       protocol = self._protocol_impl
#     else:
#       # Perhaps it was written using a different protocol.
#       protocol = None
#       for name in _protocols_registry.names:
#         key = '__%s__' % name
#         if key in ent._values:
#           blob = ent._values[key]
#           if isinstance(blob, model._BaseValue):
#             blob = blob.b_val
#           protocol = _protocols_registry.lookup_by_name(name)
#           break
#     if blob is None or protocol is None:
#       return None  # This will reveal the underlying dummy model.
#     msg = protocol.decode_message(self._message_type, blob)
#     return msg


import time
import ndb
from google.appengine.ext import testbed
from protorpc import messages
from ndb.msgprop import MessageProperty






# Example classes from protorpc/demos/guestbook/server/

class Note(messages.Message):

  text = messages.StringField(1, required=True)
  when = messages.IntegerField(2)


class GetNotesRequest(messages.Message):

  limit = messages.IntegerField(1, default=10)
  on_or_before = messages.IntegerField(2)

  class Order(messages.Enum):
    WHEN = 1
    TEXT = 2
  order = messages.EnumField(Order, 3, default=Order.WHEN)


class Notes(messages.Message):
  notes = messages.MessageField(Note, 1, repeated=True)


class DbNote(ndb.Model):

# Path: ndb/msgprop.py
# class MessageProperty(model.StructuredProperty):
#   """Messages are represented in Cloud Datastore as structured properties.
# 
#   By default, the structured property has a single subproperty
#   containing the serialized message.  This property is named 'blob_'
#   in Python but __<protocol>__ in the Datastore, where <protocol> is
#   the value of the protocol argument (default 'protobuf').
#   """
# 
#   _message_type = None
#   _indexed_fields = ()
#   _protocol = _default_protocol
#   _protocol_impl = None
# 
#   # *Replace* first positional argument with _message_type, since the
#   # _modelclass attribute is synthetic.
#   _attributes = (['_message_type'] + model.StructuredProperty._attributes[1:] +
#                  ['_indexed_fields', '_protocol'])
# 
#   @utils.positional(1 + model.StructuredProperty._positional)
#   def __init__(self, message_type, name=None,
#                indexed_fields=None, protocol=None, **kwds):
#     """Constructor.
# 
#     Args:
#       message_tyoe: A subclass of protorpc.messages.Message.
#       name: Optional datastore name (defaults to the property name).
#       indexed_fields: Optional list of dotted and undotted field names.
#       protocol: Optional protocol name default 'protobuf'.
# 
#     Additional keywords arguments specify the same options as
#     supported by StructuredProperty, except 'indexed'.
#     """
#     if not (isinstance(message_type, type) and
#             issubclass(message_type, messages.Message)):
#       raise TypeError('MessageProperty argument must be a Message subclass')
#     self._message_type = message_type
#     if indexed_fields is not None:
#       # TODO: Check they are all strings naming fields.
#       self._indexed_fields = tuple(indexed_fields)
#     # NOTE: Otherwise the class default i.e. (), prevails.
#     if protocol is None:
#       protocol = _default_protocol
#     self._protocol = protocol
#     self._protocol_impl = _protocols_registry.lookup_by_name(protocol)
#     blob_prop = model.BlobProperty('__%s__' % self._protocol)
#     # TODO: Solve this without reserving 'blob_'.
#     message_class = _make_model_class(message_type, self._indexed_fields,
#                                       blob_=blob_prop)
#     super(MessageProperty, self).__init__(message_class, name, **kwds)
# 
#   def _validate(self, msg):
#     """Validate an Enum value.
# 
#     Raises:
#       TypeError if the value is not an instance of self._message_type.
#     """
#     if not isinstance(msg, self._message_type):
#       raise TypeError('Expected a %s instance for %s property',
#                       self._message_type.__name__,
#                       self._code_name or self._name)
# 
#   def _to_base_type(self, msg):
#     """Convert a Message value to a Model instance (entity)."""
#     ent = _message_to_entity(msg, self._modelclass)
#     ent.blob_ = self._protocol_impl.encode_message(msg)
#     return ent
# 
#   def _from_base_type(self, ent):
#     """Convert a Model instance (entity) to a Message value."""
#     if ent._projection:
#       # Projection query result.  Reconstitute the message from the fields.
#       return _projected_entity_to_message(ent, self._message_type)
# 
#     blob = ent.blob_
#     if blob is not None:
#       protocol = self._protocol_impl
#     else:
#       # Perhaps it was written using a different protocol.
#       protocol = None
#       for name in _protocols_registry.names:
#         key = '__%s__' % name
#         if key in ent._values:
#           blob = ent._values[key]
#           if isinstance(blob, model._BaseValue):
#             blob = blob.b_val
#           protocol = _protocols_registry.lookup_by_name(name)
#           break
#     if blob is None or protocol is None:
#       return None  # This will reveal the underlying dummy model.
#     msg = protocol.decode_message(self._message_type, blob)
#     return msg


# Path: samples/msgprop.py
import time
import ndb
from google.appengine.ext import testbed
from protorpc import messages
from ndb.msgprop import MessageProperty







# Example classes from protorpc/demos/guestbook/server/

class Note(messages.Message):

  text = messages.StringField(1, required=True)
  when = messages.IntegerField(2)


class GetNotesRequest(messages.Message):

  limit = messages.IntegerField(1, default=10)
  on_or_before = messages.IntegerField(2)

  class Order(messages.Enum):
    WHEN = 1
    TEXT = 2
  order = messages.EnumField(Order, 3, default=Order.WHEN)


class Notes(messages.Message):
  notes = messages.MessageField(Note, 1, repeated=True)


class DbNote(ndb.Model):

  note = MessageProperty(Note)