1 # Protocol Buffers - Google's data interchange format 2 # Copyright 2008 Google Inc. All rights reserved. 3 # http://code.google.com/p/protobuf/ 4 # 5 # Redistribution and use in source and binary forms, with or without 6 # modification, are permitted provided that the following conditions are 7 # met: 8 # 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 14 # distribution. 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. 18 # 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. 30 31 """Provides type checking routines. 32 33 This module defines type checking utilities in the forms of dictionaries: 34 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 37 function. 38 TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization 39 function. 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 43 function. 44 """ 45 46 __author__ = 'robinson (at] google.com (Will Robinson)' 47 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 52 53 _FieldDescriptor = descriptor.FieldDescriptor 54 55 56 def GetTypeChecker(cpp_type, field_type): 57 """Returns a type checker for a message field of the specified types. 58 59 Args: 60 cpp_type: C++ type of the field (see descriptor.py). 61 field_type: Protocol message field type (see descriptor.py). 62 63 Returns: 64 An instance of TypeChecker which can be used to verify the types 65 of values assigned to a field of the specified type. 66 """ 67 if (cpp_type == _FieldDescriptor.CPPTYPE_STRING and 68 field_type == _FieldDescriptor.TYPE_STRING): 69 return UnicodeValueChecker() 70 return _VALUE_CHECKERS[cpp_type] 71 72 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. 77 78 class TypeChecker(object): 79 80 """Type checker used to catch type errors as early as possible 81 when the client is setting scalar fields in protocol messages. 82 """ 83 84 def __init__(self, *acceptable_types): 85 self._acceptable_types = acceptable_types 86 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) 92 93 94 # IntValueChecker and its subclasses perform integer type-checks 95 # and bounds-checks. 96 class IntValueChecker(object): 97 98 """Checker used for integer fields. Performs type-check and range check.""" 99 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) 107 108 109 class UnicodeValueChecker(object): 110 111 """Checker used for string fields.""" 112 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) 118 119 # If the value is of type 'str' make sure that it is in 7-bit ASCII 120 # encoding. 121 if isinstance(proposed_value, str): 122 try: 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.' % 128 (proposed_value)) 129 130 131 class Int32ValueChecker(IntValueChecker): 132 # We're sure to use ints instead of longs here since comparison may be more 133 # efficient. 134 _MIN = -2147483648 135 _MAX = 2147483647 136 137 138 class Uint32ValueChecker(IntValueChecker): 139 _MIN = 0 140 _MAX = (1 << 32) - 1 141 142 143 class Int64ValueChecker(IntValueChecker): 144 _MIN = -(1 << 63) 145 _MAX = (1 << 63) - 1 146 147 148 class Uint64ValueChecker(IntValueChecker): 149 _MIN = 0 150 _MAX = (1 << 64) - 1 151 152 153 # Type-checkers for all scalar CPPTYPEs. 154 _VALUE_CHECKERS = { 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( 160 float, int, long), 161 _FieldDescriptor.CPPTYPE_FLOAT: TypeChecker( 162 float, int, long), 163 _FieldDescriptor.CPPTYPE_BOOL: TypeChecker(bool, int), 164 _FieldDescriptor.CPPTYPE_ENUM: Int32ValueChecker(), 165 _FieldDescriptor.CPPTYPE_STRING: TypeChecker(str), 166 } 167 168 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 192 } 193 194 195 # Maps from field types to encoder constructors. 196 TYPE_TO_ENCODER = { 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, 215 } 216 217 218 # Maps from field types to sizer constructors. 219 TYPE_TO_SIZER = { 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, 238 } 239 240 241 # Maps from field type to a decoder constructor. 242 TYPE_TO_DECODER = { 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, 261 } 262 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, 286 } 287