| OLD | NEW |
| (Empty) |
| 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 #PY25 compatible for GAE. | |
| 32 # | |
| 33 # Copyright 2008 Google Inc. All Rights Reserved. | |
| 34 | |
| 35 """Provides type checking routines. | |
| 36 | |
| 37 This module defines type checking utilities in the forms of dictionaries: | |
| 38 | |
| 39 VALUE_CHECKERS: A dictionary of field types and a value validation object. | |
| 40 TYPE_TO_BYTE_SIZE_FN: A dictionary with field types and a size computing | |
| 41 function. | |
| 42 TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization | |
| 43 function. | |
| 44 FIELD_TYPE_TO_WIRE_TYPE: A dictionary with field typed and their | |
| 45 coresponding wire types. | |
| 46 TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization | |
| 47 function. | |
| 48 """ | |
| 49 | |
| 50 __author__ = 'robinson@google.com (Will Robinson)' | |
| 51 | |
| 52 import sys ##PY25 | |
| 53 if sys.version < '2.6': bytes = str ##PY25 | |
| 54 from google.protobuf.internal import api_implementation | |
| 55 from google.protobuf.internal import decoder | |
| 56 from google.protobuf.internal import encoder | |
| 57 from google.protobuf.internal import wire_format | |
| 58 from google.protobuf import descriptor | |
| 59 | |
| 60 _FieldDescriptor = descriptor.FieldDescriptor | |
| 61 | |
| 62 | |
| 63 def GetTypeChecker(field): | |
| 64 """Returns a type checker for a message field of the specified types. | |
| 65 | |
| 66 Args: | |
| 67 field: FieldDescriptor object for this field. | |
| 68 | |
| 69 Returns: | |
| 70 An instance of TypeChecker which can be used to verify the types | |
| 71 of values assigned to a field of the specified type. | |
| 72 """ | |
| 73 if (field.cpp_type == _FieldDescriptor.CPPTYPE_STRING and | |
| 74 field.type == _FieldDescriptor.TYPE_STRING): | |
| 75 return UnicodeValueChecker() | |
| 76 if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM: | |
| 77 return EnumValueChecker(field.enum_type) | |
| 78 return _VALUE_CHECKERS[field.cpp_type] | |
| 79 | |
| 80 | |
| 81 # None of the typecheckers below make any attempt to guard against people | |
| 82 # subclassing builtin types and doing weird things. We're not trying to | |
| 83 # protect against malicious clients here, just people accidentally shooting | |
| 84 # themselves in the foot in obvious ways. | |
| 85 | |
| 86 class TypeChecker(object): | |
| 87 | |
| 88 """Type checker used to catch type errors as early as possible | |
| 89 when the client is setting scalar fields in protocol messages. | |
| 90 """ | |
| 91 | |
| 92 def __init__(self, *acceptable_types): | |
| 93 self._acceptable_types = acceptable_types | |
| 94 | |
| 95 def CheckValue(self, proposed_value): | |
| 96 """Type check the provided value and return it. | |
| 97 | |
| 98 The returned value might have been normalized to another type. | |
| 99 """ | |
| 100 if not isinstance(proposed_value, self._acceptable_types): | |
| 101 message = ('%.1024r has type %s, but expected one of: %s' % | |
| 102 (proposed_value, type(proposed_value), self._acceptable_types)) | |
| 103 raise TypeError(message) | |
| 104 return proposed_value | |
| 105 | |
| 106 | |
| 107 # IntValueChecker and its subclasses perform integer type-checks | |
| 108 # and bounds-checks. | |
| 109 class IntValueChecker(object): | |
| 110 | |
| 111 """Checker used for integer fields. Performs type-check and range check.""" | |
| 112 | |
| 113 def CheckValue(self, proposed_value): | |
| 114 if not isinstance(proposed_value, (int, long)): | |
| 115 message = ('%.1024r has type %s, but expected one of: %s' % | |
| 116 (proposed_value, type(proposed_value), (int, long))) | |
| 117 raise TypeError(message) | |
| 118 if not self._MIN <= proposed_value <= self._MAX: | |
| 119 raise ValueError('Value out of range: %d' % proposed_value) | |
| 120 # We force 32-bit values to int and 64-bit values to long to make | |
| 121 # alternate implementations where the distinction is more significant | |
| 122 # (e.g. the C++ implementation) simpler. | |
| 123 proposed_value = self._TYPE(proposed_value) | |
| 124 return proposed_value | |
| 125 | |
| 126 | |
| 127 class EnumValueChecker(object): | |
| 128 | |
| 129 """Checker used for enum fields. Performs type-check and range check.""" | |
| 130 | |
| 131 def __init__(self, enum_type): | |
| 132 self._enum_type = enum_type | |
| 133 | |
| 134 def CheckValue(self, proposed_value): | |
| 135 if not isinstance(proposed_value, (int, long)): | |
| 136 message = ('%.1024r has type %s, but expected one of: %s' % | |
| 137 (proposed_value, type(proposed_value), (int, long))) | |
| 138 raise TypeError(message) | |
| 139 if proposed_value not in self._enum_type.values_by_number: | |
| 140 raise ValueError('Unknown enum value: %d' % proposed_value) | |
| 141 return proposed_value | |
| 142 | |
| 143 | |
| 144 class UnicodeValueChecker(object): | |
| 145 | |
| 146 """Checker used for string fields. | |
| 147 | |
| 148 Always returns a unicode value, even if the input is of type str. | |
| 149 """ | |
| 150 | |
| 151 def CheckValue(self, proposed_value): | |
| 152 if not isinstance(proposed_value, (bytes, unicode)): | |
| 153 message = ('%.1024r has type %s, but expected one of: %s' % | |
| 154 (proposed_value, type(proposed_value), (bytes, unicode))) | |
| 155 raise TypeError(message) | |
| 156 | |
| 157 # If the value is of type 'bytes' make sure that it is in 7-bit ASCII | |
| 158 # encoding. | |
| 159 if isinstance(proposed_value, bytes): | |
| 160 try: | |
| 161 proposed_value = proposed_value.decode('ascii') | |
| 162 except UnicodeDecodeError: | |
| 163 raise ValueError('%.1024r has type bytes, but isn\'t in 7-bit ASCII ' | |
| 164 'encoding. Non-ASCII strings must be converted to ' | |
| 165 'unicode objects before being added.' % | |
| 166 (proposed_value)) | |
| 167 return proposed_value | |
| 168 | |
| 169 | |
| 170 class Int32ValueChecker(IntValueChecker): | |
| 171 # We're sure to use ints instead of longs here since comparison may be more | |
| 172 # efficient. | |
| 173 _MIN = -2147483648 | |
| 174 _MAX = 2147483647 | |
| 175 _TYPE = int | |
| 176 | |
| 177 | |
| 178 class Uint32ValueChecker(IntValueChecker): | |
| 179 _MIN = 0 | |
| 180 _MAX = (1 << 32) - 1 | |
| 181 _TYPE = int | |
| 182 | |
| 183 | |
| 184 class Int64ValueChecker(IntValueChecker): | |
| 185 _MIN = -(1 << 63) | |
| 186 _MAX = (1 << 63) - 1 | |
| 187 _TYPE = long | |
| 188 | |
| 189 | |
| 190 class Uint64ValueChecker(IntValueChecker): | |
| 191 _MIN = 0 | |
| 192 _MAX = (1 << 64) - 1 | |
| 193 _TYPE = long | |
| 194 | |
| 195 | |
| 196 # Type-checkers for all scalar CPPTYPEs. | |
| 197 _VALUE_CHECKERS = { | |
| 198 _FieldDescriptor.CPPTYPE_INT32: Int32ValueChecker(), | |
| 199 _FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(), | |
| 200 _FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(), | |
| 201 _FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(), | |
| 202 _FieldDescriptor.CPPTYPE_DOUBLE: TypeChecker( | |
| 203 float, int, long), | |
| 204 _FieldDescriptor.CPPTYPE_FLOAT: TypeChecker( | |
| 205 float, int, long), | |
| 206 _FieldDescriptor.CPPTYPE_BOOL: TypeChecker(bool, int), | |
| 207 _FieldDescriptor.CPPTYPE_STRING: TypeChecker(bytes), | |
| 208 } | |
| 209 | |
| 210 | |
| 211 # Map from field type to a function F, such that F(field_num, value) | |
| 212 # gives the total byte size for a value of the given type. This | |
| 213 # byte size includes tag information and any other additional space | |
| 214 # associated with serializing "value". | |
| 215 TYPE_TO_BYTE_SIZE_FN = { | |
| 216 _FieldDescriptor.TYPE_DOUBLE: wire_format.DoubleByteSize, | |
| 217 _FieldDescriptor.TYPE_FLOAT: wire_format.FloatByteSize, | |
| 218 _FieldDescriptor.TYPE_INT64: wire_format.Int64ByteSize, | |
| 219 _FieldDescriptor.TYPE_UINT64: wire_format.UInt64ByteSize, | |
| 220 _FieldDescriptor.TYPE_INT32: wire_format.Int32ByteSize, | |
| 221 _FieldDescriptor.TYPE_FIXED64: wire_format.Fixed64ByteSize, | |
| 222 _FieldDescriptor.TYPE_FIXED32: wire_format.Fixed32ByteSize, | |
| 223 _FieldDescriptor.TYPE_BOOL: wire_format.BoolByteSize, | |
| 224 _FieldDescriptor.TYPE_STRING: wire_format.StringByteSize, | |
| 225 _FieldDescriptor.TYPE_GROUP: wire_format.GroupByteSize, | |
| 226 _FieldDescriptor.TYPE_MESSAGE: wire_format.MessageByteSize, | |
| 227 _FieldDescriptor.TYPE_BYTES: wire_format.BytesByteSize, | |
| 228 _FieldDescriptor.TYPE_UINT32: wire_format.UInt32ByteSize, | |
| 229 _FieldDescriptor.TYPE_ENUM: wire_format.EnumByteSize, | |
| 230 _FieldDescriptor.TYPE_SFIXED32: wire_format.SFixed32ByteSize, | |
| 231 _FieldDescriptor.TYPE_SFIXED64: wire_format.SFixed64ByteSize, | |
| 232 _FieldDescriptor.TYPE_SINT32: wire_format.SInt32ByteSize, | |
| 233 _FieldDescriptor.TYPE_SINT64: wire_format.SInt64ByteSize | |
| 234 } | |
| 235 | |
| 236 | |
| 237 # Maps from field types to encoder constructors. | |
| 238 TYPE_TO_ENCODER = { | |
| 239 _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleEncoder, | |
| 240 _FieldDescriptor.TYPE_FLOAT: encoder.FloatEncoder, | |
| 241 _FieldDescriptor.TYPE_INT64: encoder.Int64Encoder, | |
| 242 _FieldDescriptor.TYPE_UINT64: encoder.UInt64Encoder, | |
| 243 _FieldDescriptor.TYPE_INT32: encoder.Int32Encoder, | |
| 244 _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Encoder, | |
| 245 _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Encoder, | |
| 246 _FieldDescriptor.TYPE_BOOL: encoder.BoolEncoder, | |
| 247 _FieldDescriptor.TYPE_STRING: encoder.StringEncoder, | |
| 248 _FieldDescriptor.TYPE_GROUP: encoder.GroupEncoder, | |
| 249 _FieldDescriptor.TYPE_MESSAGE: encoder.MessageEncoder, | |
| 250 _FieldDescriptor.TYPE_BYTES: encoder.BytesEncoder, | |
| 251 _FieldDescriptor.TYPE_UINT32: encoder.UInt32Encoder, | |
| 252 _FieldDescriptor.TYPE_ENUM: encoder.EnumEncoder, | |
| 253 _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Encoder, | |
| 254 _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Encoder, | |
| 255 _FieldDescriptor.TYPE_SINT32: encoder.SInt32Encoder, | |
| 256 _FieldDescriptor.TYPE_SINT64: encoder.SInt64Encoder, | |
| 257 } | |
| 258 | |
| 259 | |
| 260 # Maps from field types to sizer constructors. | |
| 261 TYPE_TO_SIZER = { | |
| 262 _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleSizer, | |
| 263 _FieldDescriptor.TYPE_FLOAT: encoder.FloatSizer, | |
| 264 _FieldDescriptor.TYPE_INT64: encoder.Int64Sizer, | |
| 265 _FieldDescriptor.TYPE_UINT64: encoder.UInt64Sizer, | |
| 266 _FieldDescriptor.TYPE_INT32: encoder.Int32Sizer, | |
| 267 _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Sizer, | |
| 268 _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Sizer, | |
| 269 _FieldDescriptor.TYPE_BOOL: encoder.BoolSizer, | |
| 270 _FieldDescriptor.TYPE_STRING: encoder.StringSizer, | |
| 271 _FieldDescriptor.TYPE_GROUP: encoder.GroupSizer, | |
| 272 _FieldDescriptor.TYPE_MESSAGE: encoder.MessageSizer, | |
| 273 _FieldDescriptor.TYPE_BYTES: encoder.BytesSizer, | |
| 274 _FieldDescriptor.TYPE_UINT32: encoder.UInt32Sizer, | |
| 275 _FieldDescriptor.TYPE_ENUM: encoder.EnumSizer, | |
| 276 _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Sizer, | |
| 277 _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Sizer, | |
| 278 _FieldDescriptor.TYPE_SINT32: encoder.SInt32Sizer, | |
| 279 _FieldDescriptor.TYPE_SINT64: encoder.SInt64Sizer, | |
| 280 } | |
| 281 | |
| 282 | |
| 283 # Maps from field type to a decoder constructor. | |
| 284 TYPE_TO_DECODER = { | |
| 285 _FieldDescriptor.TYPE_DOUBLE: decoder.DoubleDecoder, | |
| 286 _FieldDescriptor.TYPE_FLOAT: decoder.FloatDecoder, | |
| 287 _FieldDescriptor.TYPE_INT64: decoder.Int64Decoder, | |
| 288 _FieldDescriptor.TYPE_UINT64: decoder.UInt64Decoder, | |
| 289 _FieldDescriptor.TYPE_INT32: decoder.Int32Decoder, | |
| 290 _FieldDescriptor.TYPE_FIXED64: decoder.Fixed64Decoder, | |
| 291 _FieldDescriptor.TYPE_FIXED32: decoder.Fixed32Decoder, | |
| 292 _FieldDescriptor.TYPE_BOOL: decoder.BoolDecoder, | |
| 293 _FieldDescriptor.TYPE_STRING: decoder.StringDecoder, | |
| 294 _FieldDescriptor.TYPE_GROUP: decoder.GroupDecoder, | |
| 295 _FieldDescriptor.TYPE_MESSAGE: decoder.MessageDecoder, | |
| 296 _FieldDescriptor.TYPE_BYTES: decoder.BytesDecoder, | |
| 297 _FieldDescriptor.TYPE_UINT32: decoder.UInt32Decoder, | |
| 298 _FieldDescriptor.TYPE_ENUM: decoder.EnumDecoder, | |
| 299 _FieldDescriptor.TYPE_SFIXED32: decoder.SFixed32Decoder, | |
| 300 _FieldDescriptor.TYPE_SFIXED64: decoder.SFixed64Decoder, | |
| 301 _FieldDescriptor.TYPE_SINT32: decoder.SInt32Decoder, | |
| 302 _FieldDescriptor.TYPE_SINT64: decoder.SInt64Decoder, | |
| 303 } | |
| 304 | |
| 305 # Maps from field type to expected wiretype. | |
| 306 FIELD_TYPE_TO_WIRE_TYPE = { | |
| 307 _FieldDescriptor.TYPE_DOUBLE: wire_format.WIRETYPE_FIXED64, | |
| 308 _FieldDescriptor.TYPE_FLOAT: wire_format.WIRETYPE_FIXED32, | |
| 309 _FieldDescriptor.TYPE_INT64: wire_format.WIRETYPE_VARINT, | |
| 310 _FieldDescriptor.TYPE_UINT64: wire_format.WIRETYPE_VARINT, | |
| 311 _FieldDescriptor.TYPE_INT32: wire_format.WIRETYPE_VARINT, | |
| 312 _FieldDescriptor.TYPE_FIXED64: wire_format.WIRETYPE_FIXED64, | |
| 313 _FieldDescriptor.TYPE_FIXED32: wire_format.WIRETYPE_FIXED32, | |
| 314 _FieldDescriptor.TYPE_BOOL: wire_format.WIRETYPE_VARINT, | |
| 315 _FieldDescriptor.TYPE_STRING: | |
| 316 wire_format.WIRETYPE_LENGTH_DELIMITED, | |
| 317 _FieldDescriptor.TYPE_GROUP: wire_format.WIRETYPE_START_GROUP, | |
| 318 _FieldDescriptor.TYPE_MESSAGE: | |
| 319 wire_format.WIRETYPE_LENGTH_DELIMITED, | |
| 320 _FieldDescriptor.TYPE_BYTES: | |
| 321 wire_format.WIRETYPE_LENGTH_DELIMITED, | |
| 322 _FieldDescriptor.TYPE_UINT32: wire_format.WIRETYPE_VARINT, | |
| 323 _FieldDescriptor.TYPE_ENUM: wire_format.WIRETYPE_VARINT, | |
| 324 _FieldDescriptor.TYPE_SFIXED32: wire_format.WIRETYPE_FIXED32, | |
| 325 _FieldDescriptor.TYPE_SFIXED64: wire_format.WIRETYPE_FIXED64, | |
| 326 _FieldDescriptor.TYPE_SINT32: wire_format.WIRETYPE_VARINT, | |
| 327 _FieldDescriptor.TYPE_SINT64: wire_format.WIRETYPE_VARINT, | |
| 328 } | |
| OLD | NEW |