1
1
# Protocol Buffers - Google's data interchange format
2
# Copyright 2008 Google Inc.
2
# Copyright 2008 Google Inc. All rights reserved.
3
3
# http://code.google.com/p/protobuf/
5
# Licensed under the Apache License, Version 2.0 (the "License");
6
# you may not use this file except in compliance with the License.
7
# You may obtain a copy of the License at
9
# http://www.apache.org/licenses/LICENSE-2.0
11
# Unless required by applicable law or agreed to in writing, software
12
# distributed under the License is distributed on an "AS IS" BASIS,
13
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
# See the License for the specific language governing permissions and
15
# limitations under the License.
5
# Redistribution and use in source and binary forms, with or without
6
# modification, are permitted provided that the following conditions are
9
# * Redistributions of source code must retain the above copyright
10
# notice, this list of conditions and the following disclaimer.
11
# * Redistributions in binary form must reproduce the above
12
# copyright notice, this list of conditions and the following disclaimer
13
# in the documentation and/or other materials provided with the
15
# * Neither the name of Google Inc. nor the names of its
16
# contributors may be used to endorse or promote products derived from
17
# this software without specific prior written permission.
19
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17
31
# This code is meant to work on Python 2.4 and above only.
1082
1131
cls.MergeFromString = MergeFromString
1085
def _AddIsInitializedMethod(message_descriptor, cls):
1134
def _AddIsInitializedMethod(cls):
1086
1135
"""Adds the IsInitialized method to the protocol message class."""
1087
def IsInitialized(self):
1088
fields_and_extensions = []
1089
fields_and_extensions.extend(message_descriptor.fields)
1090
fields_and_extensions.extend(
1091
self.Extensions._AllExtensionsByNumber().values())
1092
for field_or_extension in fields_and_extensions:
1093
if not _IsFieldOrExtensionInitialized(self, field_or_extension):
1096
cls.IsInitialized = IsInitialized
1136
cls.IsInitialized = _InternalIsInitialized
1139
def _MergeFieldOrExtension(destination_msg, field, value):
1140
"""Merges a specified message field into another message."""
1141
property_name = _PropertyName(field.name)
1142
is_extension = field.is_extension
1144
if not is_extension:
1145
destination = getattr(destination_msg, property_name)
1146
elif (field.label == _FieldDescriptor.LABEL_REPEATED or
1147
field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE):
1148
destination = destination_msg.Extensions[field]
1150
# Case 1 - a composite field.
1151
if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
1152
if field.label == _FieldDescriptor.LABEL_REPEATED:
1154
destination.add().MergeFrom(v)
1156
destination.MergeFrom(value)
1159
# Case 2 - a repeated field.
1160
if field.label == _FieldDescriptor.LABEL_REPEATED:
1162
destination.append(v)
1165
# Case 3 - a singular field.
1167
destination_msg.Extensions[field] = value
1169
setattr(destination_msg, property_name, value)
1172
def _AddMergeFromMethod(cls):
1173
def MergeFrom(self, msg):
1174
assert msg is not self
1175
for field in msg.ListFields():
1176
_MergeFieldOrExtension(self, field[0], field[1])
1177
cls.MergeFrom = MergeFrom
1099
1180
def _AddMessageMethods(message_descriptor, cls):
1100
1181
"""Adds implementations of all Message methods to cls."""
1102
# TODO(robinson): Add support for remaining Message methods.
1104
1182
_AddListFieldsMethod(message_descriptor, cls)
1105
1183
_AddHasFieldMethod(cls)
1106
1184
_AddClearFieldMethod(cls)
1195
# TODO(robinson): Move elsewhere?
1196
# TODO(robinson): Provide a clear() method here in addition to ClearField()?
1197
class _RepeatedScalarFieldContainer(object):
1199
"""Simple, type-checked, list-like container for holding repeated scalars.
1202
def __init__(self, message_listener, type_checker):
1205
message_listener: A MessageListener implementation.
1206
The _RepeatedScalarFieldContaininer will call this object's
1207
TransitionToNonempty() method when it transitions from being empty to
1209
type_checker: A _ValueChecker instance to run on elements inserted
1210
into this container.
1212
self._message_listener = message_listener
1213
self._type_checker = type_checker
1216
def append(self, elem):
1217
self._type_checker.CheckValue(elem)
1218
self._values.append(elem)
1219
self._message_listener.ByteSizeDirty()
1220
if len(self._values) == 1:
1221
self._message_listener.TransitionToNonempty()
1223
# List-like __getitem__() support also makes us iterable (via "iter(foo)"
1224
# or implicitly via "for i in mylist:") for free.
1225
def __getitem__(self, key):
1226
return self._values[key]
1228
def __setitem__(self, key, value):
1229
# No need to call TransitionToNonempty(), since if we're able to
1230
# set the element at this index, we were already nonempty before
1231
# this method was called.
1232
self._message_listener.ByteSizeDirty()
1233
self._type_checker.CheckValue(value)
1234
self._values[key] = value
1237
return len(self._values)
1239
def __eq__(self, other):
1242
# Special case for the same type which should be common and fast.
1243
if isinstance(other, self.__class__):
1244
return other._values == self._values
1245
# We are presumably comparing against some other sequence type.
1246
return other == self._values
1248
def __ne__(self, other):
1249
# Can't use != here since it would infinitely recurse.
1250
return not self == other
1253
# TODO(robinson): Move elsewhere?
1254
# TODO(robinson): Provide a clear() method here in addition to ClearField()?
1255
# TODO(robinson): Unify common functionality with
1256
# _RepeatedScalarFieldContaininer?
1257
class _RepeatedCompositeFieldContainer(object):
1259
"""Simple, list-like container for holding repeated composite fields.
1262
def __init__(self, message_listener, message_descriptor):
1263
"""Note that we pass in a descriptor instead of the generated directly,
1264
since at the time we construct a _RepeatedCompositeFieldContainer we
1265
haven't yet necessarily initialized the type that will be contained in the
1269
message_listener: A MessageListener implementation.
1270
The _RepeatedCompositeFieldContainer will call this object's
1271
TransitionToNonempty() method when it transitions from being empty to
1273
message_descriptor: A Descriptor instance describing the protocol type
1274
that should be present in this container. We'll use the
1275
_concrete_class field of this descriptor when the client calls add().
1277
self._message_listener = message_listener
1278
self._message_descriptor = message_descriptor
1282
new_element = self._message_descriptor._concrete_class()
1283
new_element._SetListener(self._message_listener)
1284
self._values.append(new_element)
1285
self._message_listener.ByteSizeDirty()
1286
self._message_listener.TransitionToNonempty()
1289
# List-like __getitem__() support also makes us iterable (via "iter(foo)"
1290
# or implicitly via "for i in mylist:") for free.
1291
def __getitem__(self, key):
1292
return self._values[key]
1295
return len(self._values)
1297
def __eq__(self, other):
1300
if not isinstance(other, self.__class__):
1301
raise TypeError('Can only compare repeated composite fields against '
1302
'other repeated composite fields.')
1303
return self._values == other._values
1305
def __ne__(self, other):
1306
# Can't use != here since it would infinitely recurse.
1307
return not self == other
1309
# TODO(robinson): Implement, document, and test slicing support.
1312
1275
# TODO(robinson): Move elsewhere? This file is getting pretty ridiculous...
1313
1276
# TODO(robinson): Unify error handling of "unknown extension" crap.
1314
1277
# TODO(robinson): There's so much similarity between the way that
1561
1524
# be careful when we move away from having _known_extensions as a
1562
1525
# deep-copied member of this object.
1563
1526
return dict((f.number, f) for f in self._known_extensions.itervalues())
1566
# None of the typecheckers below make any attempt to guard against people
1567
# subclassing builtin types and doing weird things. We're not trying to
1568
# protect against malicious clients here, just people accidentally shooting
1569
# themselves in the foot in obvious ways.
1571
class _TypeChecker(object):
1573
"""Type checker used to catch type errors as early as possible
1574
when the client is setting scalar fields in protocol messages.
1577
def __init__(self, *acceptable_types):
1578
self._acceptable_types = acceptable_types
1580
def CheckValue(self, proposed_value):
1581
if not isinstance(proposed_value, self._acceptable_types):
1582
message = ('%.1024r has type %s, but expected one of: %s' %
1583
(proposed_value, type(proposed_value), self._acceptable_types))
1584
raise TypeError(message)
1587
# _IntValueChecker and its subclasses perform integer type-checks
1588
# and bounds-checks.
1589
class _IntValueChecker(object):
1591
"""Checker used for integer fields. Performs type-check and range check."""
1593
def CheckValue(self, proposed_value):
1594
if not isinstance(proposed_value, (int, long)):
1595
message = ('%.1024r has type %s, but expected one of: %s' %
1596
(proposed_value, type(proposed_value), (int, long)))
1597
raise TypeError(message)
1598
if not self._MIN <= proposed_value <= self._MAX:
1599
raise ValueError('Value out of range: %d' % proposed_value)
1601
class _Int32ValueChecker(_IntValueChecker):
1602
# We're sure to use ints instead of longs here since comparison may be more
1607
class _Uint32ValueChecker(_IntValueChecker):
1609
_MAX = (1 << 32) - 1
1611
class _Int64ValueChecker(_IntValueChecker):
1613
_MAX = (1 << 63) - 1
1615
class _Uint64ValueChecker(_IntValueChecker):
1617
_MAX = (1 << 64) - 1
1620
# Type-checkers for all scalar CPPTYPEs.
1622
_FieldDescriptor.CPPTYPE_INT32: _Int32ValueChecker(),
1623
_FieldDescriptor.CPPTYPE_INT64: _Int64ValueChecker(),
1624
_FieldDescriptor.CPPTYPE_UINT32: _Uint32ValueChecker(),
1625
_FieldDescriptor.CPPTYPE_UINT64: _Uint64ValueChecker(),
1626
_FieldDescriptor.CPPTYPE_DOUBLE: _TypeChecker(
1628
_FieldDescriptor.CPPTYPE_FLOAT: _TypeChecker(
1630
_FieldDescriptor.CPPTYPE_BOOL: _TypeChecker(bool, int),
1631
_FieldDescriptor.CPPTYPE_ENUM: _Int32ValueChecker(),
1632
_FieldDescriptor.CPPTYPE_STRING: _TypeChecker(str),
1636
# Map from field type to a function F, such that F(field_num, value)
1637
# gives the total byte size for a value of the given type. This
1638
# byte size includes tag information and any other additional space
1639
# associated with serializing "value".
1640
_TYPE_TO_BYTE_SIZE_FN = {
1641
_FieldDescriptor.TYPE_DOUBLE: wire_format.DoubleByteSize,
1642
_FieldDescriptor.TYPE_FLOAT: wire_format.FloatByteSize,
1643
_FieldDescriptor.TYPE_INT64: wire_format.Int64ByteSize,
1644
_FieldDescriptor.TYPE_UINT64: wire_format.UInt64ByteSize,
1645
_FieldDescriptor.TYPE_INT32: wire_format.Int32ByteSize,
1646
_FieldDescriptor.TYPE_FIXED64: wire_format.Fixed64ByteSize,
1647
_FieldDescriptor.TYPE_FIXED32: wire_format.Fixed32ByteSize,
1648
_FieldDescriptor.TYPE_BOOL: wire_format.BoolByteSize,
1649
_FieldDescriptor.TYPE_STRING: wire_format.StringByteSize,
1650
_FieldDescriptor.TYPE_GROUP: wire_format.GroupByteSize,
1651
_FieldDescriptor.TYPE_MESSAGE: wire_format.MessageByteSize,
1652
_FieldDescriptor.TYPE_BYTES: wire_format.BytesByteSize,
1653
_FieldDescriptor.TYPE_UINT32: wire_format.UInt32ByteSize,
1654
_FieldDescriptor.TYPE_ENUM: wire_format.EnumByteSize,
1655
_FieldDescriptor.TYPE_SFIXED32: wire_format.SFixed32ByteSize,
1656
_FieldDescriptor.TYPE_SFIXED64: wire_format.SFixed64ByteSize,
1657
_FieldDescriptor.TYPE_SINT32: wire_format.SInt32ByteSize,
1658
_FieldDescriptor.TYPE_SINT64: wire_format.SInt64ByteSize
1661
# Maps from field type to an unbound Encoder method F, such that
1662
# F(encoder, field_number, value) will append the serialization
1663
# of a value of this type to the encoder.
1664
_Encoder = encoder.Encoder
1665
_TYPE_TO_SERIALIZE_METHOD = {
1666
_FieldDescriptor.TYPE_DOUBLE: _Encoder.AppendDouble,
1667
_FieldDescriptor.TYPE_FLOAT: _Encoder.AppendFloat,
1668
_FieldDescriptor.TYPE_INT64: _Encoder.AppendInt64,
1669
_FieldDescriptor.TYPE_UINT64: _Encoder.AppendUInt64,
1670
_FieldDescriptor.TYPE_INT32: _Encoder.AppendInt32,
1671
_FieldDescriptor.TYPE_FIXED64: _Encoder.AppendFixed64,
1672
_FieldDescriptor.TYPE_FIXED32: _Encoder.AppendFixed32,
1673
_FieldDescriptor.TYPE_BOOL: _Encoder.AppendBool,
1674
_FieldDescriptor.TYPE_STRING: _Encoder.AppendString,
1675
_FieldDescriptor.TYPE_GROUP: _Encoder.AppendGroup,
1676
_FieldDescriptor.TYPE_MESSAGE: _Encoder.AppendMessage,
1677
_FieldDescriptor.TYPE_BYTES: _Encoder.AppendBytes,
1678
_FieldDescriptor.TYPE_UINT32: _Encoder.AppendUInt32,
1679
_FieldDescriptor.TYPE_ENUM: _Encoder.AppendEnum,
1680
_FieldDescriptor.TYPE_SFIXED32: _Encoder.AppendSFixed32,
1681
_FieldDescriptor.TYPE_SFIXED64: _Encoder.AppendSFixed64,
1682
_FieldDescriptor.TYPE_SINT32: _Encoder.AppendSInt32,
1683
_FieldDescriptor.TYPE_SINT64: _Encoder.AppendSInt64,
1686
# Maps from field type to expected wiretype.
1687
_FIELD_TYPE_TO_WIRE_TYPE = {
1688
_FieldDescriptor.TYPE_DOUBLE: wire_format.WIRETYPE_FIXED64,
1689
_FieldDescriptor.TYPE_FLOAT: wire_format.WIRETYPE_FIXED32,
1690
_FieldDescriptor.TYPE_INT64: wire_format.WIRETYPE_VARINT,
1691
_FieldDescriptor.TYPE_UINT64: wire_format.WIRETYPE_VARINT,
1692
_FieldDescriptor.TYPE_INT32: wire_format.WIRETYPE_VARINT,
1693
_FieldDescriptor.TYPE_FIXED64: wire_format.WIRETYPE_FIXED64,
1694
_FieldDescriptor.TYPE_FIXED32: wire_format.WIRETYPE_FIXED32,
1695
_FieldDescriptor.TYPE_BOOL: wire_format.WIRETYPE_VARINT,
1696
_FieldDescriptor.TYPE_STRING:
1697
wire_format.WIRETYPE_LENGTH_DELIMITED,
1698
_FieldDescriptor.TYPE_GROUP: wire_format.WIRETYPE_START_GROUP,
1699
_FieldDescriptor.TYPE_MESSAGE:
1700
wire_format.WIRETYPE_LENGTH_DELIMITED,
1701
_FieldDescriptor.TYPE_BYTES:
1702
wire_format.WIRETYPE_LENGTH_DELIMITED,
1703
_FieldDescriptor.TYPE_UINT32: wire_format.WIRETYPE_VARINT,
1704
_FieldDescriptor.TYPE_ENUM: wire_format.WIRETYPE_VARINT,
1705
_FieldDescriptor.TYPE_SFIXED32: wire_format.WIRETYPE_FIXED32,
1706
_FieldDescriptor.TYPE_SFIXED64: wire_format.WIRETYPE_FIXED64,
1707
_FieldDescriptor.TYPE_SINT32: wire_format.WIRETYPE_VARINT,
1708
_FieldDescriptor.TYPE_SINT64: wire_format.WIRETYPE_VARINT,
1711
# Maps from field type to an unbound Decoder method F,
1712
# such that F(decoder) will read a field of the requested type.
1714
# Note that Message and Group are intentionally missing here.
1715
# They're handled by _RecursivelyMerge().
1716
_Decoder = decoder.Decoder
1717
_TYPE_TO_DESERIALIZE_METHOD = {
1718
_FieldDescriptor.TYPE_DOUBLE: _Decoder.ReadDouble,
1719
_FieldDescriptor.TYPE_FLOAT: _Decoder.ReadFloat,
1720
_FieldDescriptor.TYPE_INT64: _Decoder.ReadInt64,
1721
_FieldDescriptor.TYPE_UINT64: _Decoder.ReadUInt64,
1722
_FieldDescriptor.TYPE_INT32: _Decoder.ReadInt32,
1723
_FieldDescriptor.TYPE_FIXED64: _Decoder.ReadFixed64,
1724
_FieldDescriptor.TYPE_FIXED32: _Decoder.ReadFixed32,
1725
_FieldDescriptor.TYPE_BOOL: _Decoder.ReadBool,
1726
_FieldDescriptor.TYPE_STRING: _Decoder.ReadString,
1727
_FieldDescriptor.TYPE_BYTES: _Decoder.ReadBytes,
1728
_FieldDescriptor.TYPE_UINT32: _Decoder.ReadUInt32,
1729
_FieldDescriptor.TYPE_ENUM: _Decoder.ReadEnum,
1730
_FieldDescriptor.TYPE_SFIXED32: _Decoder.ReadSFixed32,
1731
_FieldDescriptor.TYPE_SFIXED64: _Decoder.ReadSFixed64,
1732
_FieldDescriptor.TYPE_SINT32: _Decoder.ReadSInt32,
1733
_FieldDescriptor.TYPE_SINT64: _Decoder.ReadSInt64,