15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Protocol Buffers - Google's data interchange format 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright 2008 Google Inc. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# http://code.google.com/p/protobuf/ 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Redistribution and use in source and binary forms, with or without 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# modification, are permitted provided that the following conditions are 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# met: 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# * Redistributions of source code must retain the above copyright 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# notice, this list of conditions and the following disclaimer. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# * Redistributions in binary form must reproduce the above 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# copyright notice, this list of conditions and the following disclaimer 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# in the documentation and/or other materials provided with the 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# distribution. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# * Neither the name of Google Inc. nor the names of its 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# contributors may be used to endorse or promote products derived from 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# this software without specific prior written permission. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# TODO(robinson): We should just make these methods all "pure-virtual" and move 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# all implementation out, into reflection.py for now. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""Contains an abstract base class for protocol messages.""" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)__author__ = 'robinson@google.com (Will Robinson)' 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Error(Exception): pass 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DecodeError(Error): pass 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class EncodeError(Error): pass 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Message(object): 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Abstract base class for protocol messages. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Protocol message classes are almost always generated by the protocol 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compiler. These generated types subclass Message and implement the methods 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shown below. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TODO(robinson): Link to an HTML document here. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TODO(robinson): Document that instances of this class will also 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) have an Extensions attribute with __getitem__ and __setitem__. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Again, not sure how to best convey this. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TODO(robinson): Document that the class must also have a static 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RegisterExtension(extension_field) method. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Not sure how to best express at this point. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # TODO(robinson): Document these fields and methods. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __slots__ = [] 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DESCRIPTOR = None 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __deepcopy__(self, memo=None): 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clone = type(self)() 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clone.MergeFrom(self) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return clone 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __eq__(self, other_msg): 763d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch """Recursively compares two messages by value and structure.""" 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __ne__(self, other_msg): 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Can't just say self != other_msg, since that would infinitely recurse. :) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return not self == other_msg 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __hash__(self): 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise TypeError('unhashable object') 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __str__(self): 873d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch """Outputs a human-readable representation of the message.""" 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __unicode__(self): 913d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch """Outputs a human-readable representation of the message.""" 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def MergeFrom(self, other_msg): 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Merges the contents of the specified message into current message. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) This method merges the contents of the specified message into the current 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message. Singular fields that are set in the specified message overwrite 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) the corresponding fields in the current message. Repeated fields are 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) appended. Singular sub-messages and groups are recursively merged. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Args: 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_msg: Message to merge into the current message. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def CopyFrom(self, other_msg): 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Copies the content of the specified message into the current message. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The method clears the current message and then merges the specified 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message using MergeFrom. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Args: 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_msg: Message to copy into the current one. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self is other_msg: 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.Clear() 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.MergeFrom(other_msg) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def Clear(self): 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Clears all data that was set in the message.""" 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def SetInParent(self): 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Mark this as present in the parent. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) This normally happens automatically when you assign a field of a 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sub-message, but sometimes you want to make the sub-message 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) present while keeping it empty. If you find yourself using this, 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) you may want to reconsider your design.""" 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def IsInitialized(self): 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Checks if the message is initialized. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Returns: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The method returns True if the message is initialized (i.e. all of its 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) required fields are set). 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # TODO(robinson): MergeFromString() should probably return None and be 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # implemented in terms of a helper that returns the # of bytes read. Our 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # deserialization routines would use the helper when recursively 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # deserializing, but the end user would almost always just want the no-return 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # MergeFromString(). 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def MergeFromString(self, serialized): 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Merges serialized protocol buffer data into this message. 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) When we find a field in |serialized| that is already present 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in this message: 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) - If it's a "repeated" field, we append to the end of our list. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) - Else, if it's a scalar, we overwrite our field. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) - Else, (it's a nonrepeated composite), we recursively merge 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) into the existing composite. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TODO(robinson): Document handling of unknown fields. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Args: 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) serialized: Any object that allows us to call buffer(serialized) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to access a string of bytes using the buffer interface. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TODO(robinson): When we switch to a helper, this will return None. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Returns: 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The number of bytes read from |serialized|. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) For non-group messages, this will always be len(serialized), 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) but for messages which are actually groups, this will 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generally be less than len(serialized), since we must 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stop when we reach an END_GROUP tag. Note that if 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) we *do* stop because of an END_GROUP tag, the number 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) of bytes returned does not include the bytes 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for the END_GROUP tag information. 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def ParseFromString(self, serialized): 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Like MergeFromString(), except we clear the object first.""" 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.Clear() 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.MergeFromString(serialized) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def SerializeToString(self): 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Serializes the protocol message to a binary string. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Returns: 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) A binary string representation of the message if all of the required 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fields in the message are set (i.e. the message is initialized). 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Raises: 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message.EncodeError if the message isn't initialized. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def SerializePartialToString(self): 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Serializes the protocol message to a binary string. 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) This method is similar to SerializeToString but doesn't check if the 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message is initialized. 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Returns: 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) A string representation of the partial message. 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # TODO(robinson): Decide whether we like these better 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # than auto-generated has_foo() and clear_foo() methods 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # on the instances themselves. This way is less consistent 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # with C++, but it makes reflection-type access easier and 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # reduces the number of magically autogenerated things. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # TODO(robinson): Be sure to document (and test) exactly 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # which field names are accepted here. Are we case-sensitive? 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # What do we do with fields that share names with Python keywords 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # like 'lambda' and 'yield'? 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # nnorwitz says: 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # """ 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Typically (in python), an underscore is appended to names that are 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # keywords. So they would become lambda_ or yield_. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # """ 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def ListFields(self): 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Returns a list of (FieldDescriptor, value) tuples for all 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fields in the message which are not empty. A singular field is non-empty 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if HasField() would return true, and a repeated field is non-empty if 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it contains at least one element. The fields are ordered by field 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number""" 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def HasField(self, field_name): 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Checks if a certain field is set for the message. Note if the 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_name is not defined in the message descriptor, ValueError will be 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raised.""" 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def ClearField(self, field_name): 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def HasExtension(self, extension_handle): 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def ClearExtension(self, extension_handle): 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def ByteSize(self): 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Returns the serialized size of this message. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Recursively calls ByteSize() on all contained messages. 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _SetListener(self, message_listener): 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Internal method used by the protocol message implementation. 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Clients should not call this directly. 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Sets a listener that this message will call on certain state transitions. 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) The purpose of this method is to register back-edges from children to 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parents at runtime, for the purpose of setting "has" bits and 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) byte-size-dirty bits in the parent and ancestor objects whenever a child or 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descendant object is modified. 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) If the client wants to disconnect this Message from the object tree, she 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicitly sets callback to None. 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) If message_listener is None, unregisters any existing listener. Otherwise, 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_listener must implement the MessageListener interface in 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal/message_listener.py, and we discard any listener registered 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) via a previous _SetListener() call. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise NotImplementedError 2723d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 2733d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch def __getstate__(self): 2743d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch """Support the pickle protocol.""" 2753d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch return dict(serialized=self.SerializePartialToString()) 2763d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 2773d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch def __setstate__(self, state): 2783d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch """Support the pickle protocol.""" 2793d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch self.__init__() 2803d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch self.ParseFromString(state['serialized']) 281