1
# Protocol Buffers - Google's data interchange format
2
# Copyright 2008 Google Inc. All rights reserved.
3
# http://code.google.com/p/protobuf/
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.
31
"""Provides type checking routines.
33
This module defines type checking utilities in the forms of dictionaries:
35
VALUE_CHECKERS: A dictionary of field types and a value validation object.
36
TYPE_TO_BYTE_SIZE_FN: A dictionary with field types and a size computing
38
TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization
40
FIELD_TYPE_TO_WIRE_TYPE: A dictionary with field typed and their
41
coresponding wire types.
42
TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization
46
__author__ = 'robinson@google.com (Will Robinson)'
48
from google.protobuf.internal import decoder
49
from google.protobuf.internal import encoder
50
from google.protobuf.internal import wire_format
51
from google.protobuf import descriptor
53
_FieldDescriptor = descriptor.FieldDescriptor
56
def GetTypeChecker(cpp_type, field_type):
57
"""Returns a type checker for a message field of the specified types.
60
cpp_type: C++ type of the field (see descriptor.py).
61
field_type: Protocol message field type (see descriptor.py).
64
An instance of TypeChecker which can be used to verify the types
65
of values assigned to a field of the specified type.
67
if (cpp_type == _FieldDescriptor.CPPTYPE_STRING and
68
field_type == _FieldDescriptor.TYPE_STRING):
69
return UnicodeValueChecker()
70
return _VALUE_CHECKERS[cpp_type]
73
# None of the typecheckers below make any attempt to guard against people
74
# subclassing builtin types and doing weird things. We're not trying to
75
# protect against malicious clients here, just people accidentally shooting
76
# themselves in the foot in obvious ways.
78
class TypeChecker(object):
80
"""Type checker used to catch type errors as early as possible
81
when the client is setting scalar fields in protocol messages.
84
def __init__(self, *acceptable_types):
85
self._acceptable_types = acceptable_types
87
def CheckValue(self, proposed_value):
88
if not isinstance(proposed_value, self._acceptable_types):
89
message = ('%.1024r has type %s, but expected one of: %s' %
90
(proposed_value, type(proposed_value), self._acceptable_types))
91
raise TypeError(message)
94
# IntValueChecker and its subclasses perform integer type-checks
96
class IntValueChecker(object):
98
"""Checker used for integer fields. Performs type-check and range check."""
100
def CheckValue(self, proposed_value):
101
if not isinstance(proposed_value, (int, long)):
102
message = ('%.1024r has type %s, but expected one of: %s' %
103
(proposed_value, type(proposed_value), (int, long)))
104
raise TypeError(message)
105
if not self._MIN <= proposed_value <= self._MAX:
106
raise ValueError('Value out of range: %d' % proposed_value)
109
class UnicodeValueChecker(object):
111
"""Checker used for string fields."""
113
def CheckValue(self, proposed_value):
114
if not isinstance(proposed_value, (str, unicode)):
115
message = ('%.1024r has type %s, but expected one of: %s' %
116
(proposed_value, type(proposed_value), (str, unicode)))
117
raise TypeError(message)
119
# If the value is of type 'str' make sure that it is in 7-bit ASCII
121
if isinstance(proposed_value, str):
123
unicode(proposed_value, 'ascii')
124
except UnicodeDecodeError:
125
raise ValueError('%.1024r has type str, but isn\'t in 7-bit ASCII '
126
'encoding. Non-ASCII strings must be converted to '
127
'unicode objects before being added.' %
131
class Int32ValueChecker(IntValueChecker):
132
# We're sure to use ints instead of longs here since comparison may be more
138
class Uint32ValueChecker(IntValueChecker):
143
class Int64ValueChecker(IntValueChecker):
148
class Uint64ValueChecker(IntValueChecker):
153
# Type-checkers for all scalar CPPTYPEs.
155
_FieldDescriptor.CPPTYPE_INT32: Int32ValueChecker(),
156
_FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(),
157
_FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(),
158
_FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(),
159
_FieldDescriptor.CPPTYPE_DOUBLE: TypeChecker(
161
_FieldDescriptor.CPPTYPE_FLOAT: TypeChecker(
163
_FieldDescriptor.CPPTYPE_BOOL: TypeChecker(bool, int),
164
_FieldDescriptor.CPPTYPE_ENUM: Int32ValueChecker(),
165
_FieldDescriptor.CPPTYPE_STRING: TypeChecker(str),
169
# Map from field type to a function F, such that F(field_num, value)
170
# gives the total byte size for a value of the given type. This
171
# byte size includes tag information and any other additional space
172
# associated with serializing "value".
173
TYPE_TO_BYTE_SIZE_FN = {
174
_FieldDescriptor.TYPE_DOUBLE: wire_format.DoubleByteSize,
175
_FieldDescriptor.TYPE_FLOAT: wire_format.FloatByteSize,
176
_FieldDescriptor.TYPE_INT64: wire_format.Int64ByteSize,
177
_FieldDescriptor.TYPE_UINT64: wire_format.UInt64ByteSize,
178
_FieldDescriptor.TYPE_INT32: wire_format.Int32ByteSize,
179
_FieldDescriptor.TYPE_FIXED64: wire_format.Fixed64ByteSize,
180
_FieldDescriptor.TYPE_FIXED32: wire_format.Fixed32ByteSize,
181
_FieldDescriptor.TYPE_BOOL: wire_format.BoolByteSize,
182
_FieldDescriptor.TYPE_STRING: wire_format.StringByteSize,
183
_FieldDescriptor.TYPE_GROUP: wire_format.GroupByteSize,
184
_FieldDescriptor.TYPE_MESSAGE: wire_format.MessageByteSize,
185
_FieldDescriptor.TYPE_BYTES: wire_format.BytesByteSize,
186
_FieldDescriptor.TYPE_UINT32: wire_format.UInt32ByteSize,
187
_FieldDescriptor.TYPE_ENUM: wire_format.EnumByteSize,
188
_FieldDescriptor.TYPE_SFIXED32: wire_format.SFixed32ByteSize,
189
_FieldDescriptor.TYPE_SFIXED64: wire_format.SFixed64ByteSize,
190
_FieldDescriptor.TYPE_SINT32: wire_format.SInt32ByteSize,
191
_FieldDescriptor.TYPE_SINT64: wire_format.SInt64ByteSize
195
# Maps from field types to encoder constructors.
197
_FieldDescriptor.TYPE_DOUBLE: encoder.DoubleEncoder,
198
_FieldDescriptor.TYPE_FLOAT: encoder.FloatEncoder,
199
_FieldDescriptor.TYPE_INT64: encoder.Int64Encoder,
200
_FieldDescriptor.TYPE_UINT64: encoder.UInt64Encoder,
201
_FieldDescriptor.TYPE_INT32: encoder.Int32Encoder,
202
_FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Encoder,
203
_FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Encoder,
204
_FieldDescriptor.TYPE_BOOL: encoder.BoolEncoder,
205
_FieldDescriptor.TYPE_STRING: encoder.StringEncoder,
206
_FieldDescriptor.TYPE_GROUP: encoder.GroupEncoder,
207
_FieldDescriptor.TYPE_MESSAGE: encoder.MessageEncoder,
208
_FieldDescriptor.TYPE_BYTES: encoder.BytesEncoder,
209
_FieldDescriptor.TYPE_UINT32: encoder.UInt32Encoder,
210
_FieldDescriptor.TYPE_ENUM: encoder.EnumEncoder,
211
_FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Encoder,
212
_FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Encoder,
213
_FieldDescriptor.TYPE_SINT32: encoder.SInt32Encoder,
214
_FieldDescriptor.TYPE_SINT64: encoder.SInt64Encoder,
218
# Maps from field types to sizer constructors.
220
_FieldDescriptor.TYPE_DOUBLE: encoder.DoubleSizer,
221
_FieldDescriptor.TYPE_FLOAT: encoder.FloatSizer,
222
_FieldDescriptor.TYPE_INT64: encoder.Int64Sizer,
223
_FieldDescriptor.TYPE_UINT64: encoder.UInt64Sizer,
224
_FieldDescriptor.TYPE_INT32: encoder.Int32Sizer,
225
_FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Sizer,
226
_FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Sizer,
227
_FieldDescriptor.TYPE_BOOL: encoder.BoolSizer,
228
_FieldDescriptor.TYPE_STRING: encoder.StringSizer,
229
_FieldDescriptor.TYPE_GROUP: encoder.GroupSizer,
230
_FieldDescriptor.TYPE_MESSAGE: encoder.MessageSizer,
231
_FieldDescriptor.TYPE_BYTES: encoder.BytesSizer,
232
_FieldDescriptor.TYPE_UINT32: encoder.UInt32Sizer,
233
_FieldDescriptor.TYPE_ENUM: encoder.EnumSizer,
234
_FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Sizer,
235
_FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Sizer,
236
_FieldDescriptor.TYPE_SINT32: encoder.SInt32Sizer,
237
_FieldDescriptor.TYPE_SINT64: encoder.SInt64Sizer,
241
# Maps from field type to a decoder constructor.
243
_FieldDescriptor.TYPE_DOUBLE: decoder.DoubleDecoder,
244
_FieldDescriptor.TYPE_FLOAT: decoder.FloatDecoder,
245
_FieldDescriptor.TYPE_INT64: decoder.Int64Decoder,
246
_FieldDescriptor.TYPE_UINT64: decoder.UInt64Decoder,
247
_FieldDescriptor.TYPE_INT32: decoder.Int32Decoder,
248
_FieldDescriptor.TYPE_FIXED64: decoder.Fixed64Decoder,
249
_FieldDescriptor.TYPE_FIXED32: decoder.Fixed32Decoder,
250
_FieldDescriptor.TYPE_BOOL: decoder.BoolDecoder,
251
_FieldDescriptor.TYPE_STRING: decoder.StringDecoder,
252
_FieldDescriptor.TYPE_GROUP: decoder.GroupDecoder,
253
_FieldDescriptor.TYPE_MESSAGE: decoder.MessageDecoder,
254
_FieldDescriptor.TYPE_BYTES: decoder.BytesDecoder,
255
_FieldDescriptor.TYPE_UINT32: decoder.UInt32Decoder,
256
_FieldDescriptor.TYPE_ENUM: decoder.EnumDecoder,
257
_FieldDescriptor.TYPE_SFIXED32: decoder.SFixed32Decoder,
258
_FieldDescriptor.TYPE_SFIXED64: decoder.SFixed64Decoder,
259
_FieldDescriptor.TYPE_SINT32: decoder.SInt32Decoder,
260
_FieldDescriptor.TYPE_SINT64: decoder.SInt64Decoder,
263
# Maps from field type to expected wiretype.
264
FIELD_TYPE_TO_WIRE_TYPE = {
265
_FieldDescriptor.TYPE_DOUBLE: wire_format.WIRETYPE_FIXED64,
266
_FieldDescriptor.TYPE_FLOAT: wire_format.WIRETYPE_FIXED32,
267
_FieldDescriptor.TYPE_INT64: wire_format.WIRETYPE_VARINT,
268
_FieldDescriptor.TYPE_UINT64: wire_format.WIRETYPE_VARINT,
269
_FieldDescriptor.TYPE_INT32: wire_format.WIRETYPE_VARINT,
270
_FieldDescriptor.TYPE_FIXED64: wire_format.WIRETYPE_FIXED64,
271
_FieldDescriptor.TYPE_FIXED32: wire_format.WIRETYPE_FIXED32,
272
_FieldDescriptor.TYPE_BOOL: wire_format.WIRETYPE_VARINT,
273
_FieldDescriptor.TYPE_STRING:
274
wire_format.WIRETYPE_LENGTH_DELIMITED,
275
_FieldDescriptor.TYPE_GROUP: wire_format.WIRETYPE_START_GROUP,
276
_FieldDescriptor.TYPE_MESSAGE:
277
wire_format.WIRETYPE_LENGTH_DELIMITED,
278
_FieldDescriptor.TYPE_BYTES:
279
wire_format.WIRETYPE_LENGTH_DELIMITED,
280
_FieldDescriptor.TYPE_UINT32: wire_format.WIRETYPE_VARINT,
281
_FieldDescriptor.TYPE_ENUM: wire_format.WIRETYPE_VARINT,
282
_FieldDescriptor.TYPE_SFIXED32: wire_format.WIRETYPE_FIXED32,
283
_FieldDescriptor.TYPE_SFIXED64: wire_format.WIRETYPE_FIXED64,
284
_FieldDescriptor.TYPE_SINT32: wire_format.WIRETYPE_VARINT,
285
_FieldDescriptor.TYPE_SINT64: wire_format.WIRETYPE_VARINT,