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 33This module defines type checking utilities in the forms of dictionaries: 34 35VALUE_CHECKERS: A dictionary of field types and a value validation object. 36TYPE_TO_BYTE_SIZE_FN: A dictionary with field types and a size computing 37 function. 38TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization 39 function. 40FIELD_TYPE_TO_WIRE_TYPE: A dictionary with field typed and their 41 coresponding wire types. 42TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization 43 function. 44""" 45 46__author__ = 'robinson@google.com (Will Robinson)' 47 48from google.protobuf.internal import decoder 49from google.protobuf.internal import encoder 50from google.protobuf.internal import wire_format 51from google.protobuf import descriptor 52 53_FieldDescriptor = descriptor.FieldDescriptor 54 55 56def 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 78class 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. 96class 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 109class 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 131class 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 138class Uint32ValueChecker(IntValueChecker): 139 _MIN = 0 140 _MAX = (1 << 32) - 1 141 142 143class Int64ValueChecker(IntValueChecker): 144 _MIN = -(1 << 63) 145 _MAX = (1 << 63) - 1 146 147 148class 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". 173TYPE_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. 196TYPE_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. 219TYPE_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. 242TYPE_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. 264FIELD_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