Index: third_party/google/protobuf/message.py |
diff --git a/third_party/google/protobuf/message.py b/third_party/google/protobuf/message.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..37b0af14579a66d86fc18d0399bc1a52cdb769d5 |
--- /dev/null |
+++ b/third_party/google/protobuf/message.py |
@@ -0,0 +1,284 @@ |
+# Protocol Buffers - Google's data interchange format |
+# Copyright 2008 Google Inc. All rights reserved. |
+# http://code.google.com/p/protobuf/ |
+# |
+# Redistribution and use in source and binary forms, with or without |
+# modification, are permitted provided that the following conditions are |
+# met: |
+# |
+# * Redistributions of source code must retain the above copyright |
+# notice, this list of conditions and the following disclaimer. |
+# * Redistributions in binary form must reproduce the above |
+# copyright notice, this list of conditions and the following disclaimer |
+# in the documentation and/or other materials provided with the |
+# distribution. |
+# * Neither the name of Google Inc. nor the names of its |
+# contributors may be used to endorse or promote products derived from |
+# this software without specific prior written permission. |
+# |
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ |
+# TODO(robinson): We should just make these methods all "pure-virtual" and move |
+# all implementation out, into reflection.py for now. |
+ |
+ |
+"""Contains an abstract base class for protocol messages.""" |
+ |
+__author__ = 'robinson@google.com (Will Robinson)' |
+ |
+ |
+class Error(Exception): pass |
+class DecodeError(Error): pass |
+class EncodeError(Error): pass |
+ |
+ |
+class Message(object): |
+ |
+ """Abstract base class for protocol messages. |
+ |
+ Protocol message classes are almost always generated by the protocol |
+ compiler. These generated types subclass Message and implement the methods |
+ shown below. |
+ |
+ TODO(robinson): Link to an HTML document here. |
+ |
+ TODO(robinson): Document that instances of this class will also |
+ have an Extensions attribute with __getitem__ and __setitem__. |
+ Again, not sure how to best convey this. |
+ |
+ TODO(robinson): Document that the class must also have a static |
+ RegisterExtension(extension_field) method. |
+ Not sure how to best express at this point. |
+ """ |
+ |
+ # TODO(robinson): Document these fields and methods. |
+ |
+ __slots__ = [] |
+ |
+ DESCRIPTOR = None |
+ |
+ def __deepcopy__(self, memo=None): |
+ clone = type(self)() |
+ clone.MergeFrom(self) |
+ return clone |
+ |
+ def __eq__(self, other_msg): |
+ """Recursively compares two messages by value and structure.""" |
+ raise NotImplementedError |
+ |
+ def __ne__(self, other_msg): |
+ # Can't just say self != other_msg, since that would infinitely recurse. :) |
+ return not self == other_msg |
+ |
+ def __hash__(self): |
+ raise TypeError('unhashable object') |
+ |
+ def __str__(self): |
+ """Outputs a human-readable representation of the message.""" |
+ raise NotImplementedError |
+ |
+ def __unicode__(self): |
+ """Outputs a human-readable representation of the message.""" |
+ raise NotImplementedError |
+ |
+ def MergeFrom(self, other_msg): |
+ """Merges the contents of the specified message into current message. |
+ |
+ This method merges the contents of the specified message into the current |
+ message. Singular fields that are set in the specified message overwrite |
+ the corresponding fields in the current message. Repeated fields are |
+ appended. Singular sub-messages and groups are recursively merged. |
+ |
+ Args: |
+ other_msg: Message to merge into the current message. |
+ """ |
+ raise NotImplementedError |
+ |
+ def CopyFrom(self, other_msg): |
+ """Copies the content of the specified message into the current message. |
+ |
+ The method clears the current message and then merges the specified |
+ message using MergeFrom. |
+ |
+ Args: |
+ other_msg: Message to copy into the current one. |
+ """ |
+ if self is other_msg: |
+ return |
+ self.Clear() |
+ self.MergeFrom(other_msg) |
+ |
+ def Clear(self): |
+ """Clears all data that was set in the message.""" |
+ raise NotImplementedError |
+ |
+ def SetInParent(self): |
+ """Mark this as present in the parent. |
+ |
+ This normally happens automatically when you assign a field of a |
+ sub-message, but sometimes you want to make the sub-message |
+ present while keeping it empty. If you find yourself using this, |
+ you may want to reconsider your design.""" |
+ raise NotImplementedError |
+ |
+ def IsInitialized(self): |
+ """Checks if the message is initialized. |
+ |
+ Returns: |
+ The method returns True if the message is initialized (i.e. all of its |
+ required fields are set). |
+ """ |
+ raise NotImplementedError |
+ |
+ # TODO(robinson): MergeFromString() should probably return None and be |
+ # implemented in terms of a helper that returns the # of bytes read. Our |
+ # deserialization routines would use the helper when recursively |
+ # deserializing, but the end user would almost always just want the no-return |
+ # MergeFromString(). |
+ |
+ def MergeFromString(self, serialized): |
+ """Merges serialized protocol buffer data into this message. |
+ |
+ When we find a field in |serialized| that is already present |
+ in this message: |
+ - If it's a "repeated" field, we append to the end of our list. |
+ - Else, if it's a scalar, we overwrite our field. |
+ - Else, (it's a nonrepeated composite), we recursively merge |
+ into the existing composite. |
+ |
+ TODO(robinson): Document handling of unknown fields. |
+ |
+ Args: |
+ serialized: Any object that allows us to call buffer(serialized) |
+ to access a string of bytes using the buffer interface. |
+ |
+ TODO(robinson): When we switch to a helper, this will return None. |
+ |
+ Returns: |
+ The number of bytes read from |serialized|. |
+ For non-group messages, this will always be len(serialized), |
+ but for messages which are actually groups, this will |
+ generally be less than len(serialized), since we must |
+ stop when we reach an END_GROUP tag. Note that if |
+ we *do* stop because of an END_GROUP tag, the number |
+ of bytes returned does not include the bytes |
+ for the END_GROUP tag information. |
+ """ |
+ raise NotImplementedError |
+ |
+ def ParseFromString(self, serialized): |
+ """Parse serialized protocol buffer data into this message. |
+ |
+ Like MergeFromString(), except we clear the object first and |
+ do not return the value that MergeFromString returns. |
+ """ |
+ self.Clear() |
+ self.MergeFromString(serialized) |
+ |
+ def SerializeToString(self): |
+ """Serializes the protocol message to a binary string. |
+ |
+ Returns: |
+ A binary string representation of the message if all of the required |
+ fields in the message are set (i.e. the message is initialized). |
+ |
+ Raises: |
+ message.EncodeError if the message isn't initialized. |
+ """ |
+ raise NotImplementedError |
+ |
+ def SerializePartialToString(self): |
+ """Serializes the protocol message to a binary string. |
+ |
+ This method is similar to SerializeToString but doesn't check if the |
+ message is initialized. |
+ |
+ Returns: |
+ A string representation of the partial message. |
+ """ |
+ raise NotImplementedError |
+ |
+ # TODO(robinson): Decide whether we like these better |
+ # than auto-generated has_foo() and clear_foo() methods |
+ # on the instances themselves. This way is less consistent |
+ # with C++, but it makes reflection-type access easier and |
+ # reduces the number of magically autogenerated things. |
+ # |
+ # TODO(robinson): Be sure to document (and test) exactly |
+ # which field names are accepted here. Are we case-sensitive? |
+ # What do we do with fields that share names with Python keywords |
+ # like 'lambda' and 'yield'? |
+ # |
+ # nnorwitz says: |
+ # """ |
+ # Typically (in python), an underscore is appended to names that are |
+ # keywords. So they would become lambda_ or yield_. |
+ # """ |
+ def ListFields(self): |
+ """Returns a list of (FieldDescriptor, value) tuples for all |
+ fields in the message which are not empty. A singular field is non-empty |
+ if HasField() would return true, and a repeated field is non-empty if |
+ it contains at least one element. The fields are ordered by field |
+ number""" |
+ raise NotImplementedError |
+ |
+ def HasField(self, field_name): |
+ """Checks if a certain field is set for the message. Note if the |
+ field_name is not defined in the message descriptor, ValueError will be |
+ raised.""" |
+ raise NotImplementedError |
+ |
+ def ClearField(self, field_name): |
+ raise NotImplementedError |
+ |
+ def HasExtension(self, extension_handle): |
+ raise NotImplementedError |
+ |
+ def ClearExtension(self, extension_handle): |
+ raise NotImplementedError |
+ |
+ def ByteSize(self): |
+ """Returns the serialized size of this message. |
+ Recursively calls ByteSize() on all contained messages. |
+ """ |
+ raise NotImplementedError |
+ |
+ def _SetListener(self, message_listener): |
+ """Internal method used by the protocol message implementation. |
+ Clients should not call this directly. |
+ |
+ Sets a listener that this message will call on certain state transitions. |
+ |
+ The purpose of this method is to register back-edges from children to |
+ parents at runtime, for the purpose of setting "has" bits and |
+ byte-size-dirty bits in the parent and ancestor objects whenever a child or |
+ descendant object is modified. |
+ |
+ If the client wants to disconnect this Message from the object tree, she |
+ explicitly sets callback to None. |
+ |
+ If message_listener is None, unregisters any existing listener. Otherwise, |
+ message_listener must implement the MessageListener interface in |
+ internal/message_listener.py, and we discard any listener registered |
+ via a previous _SetListener() call. |
+ """ |
+ raise NotImplementedError |
+ |
+ def __getstate__(self): |
+ """Support the pickle protocol.""" |
+ return dict(serialized=self.SerializePartialToString()) |
+ |
+ def __setstate__(self, state): |
+ """Support the pickle protocol.""" |
+ self.__init__() |
+ self.ParseFromString(state['serialized']) |