Index: third_party/protobuf/python/google/protobuf/internal/type_checkers.py |
diff --git a/third_party/protobuf/python/google/protobuf/internal/type_checkers.py b/third_party/protobuf/python/google/protobuf/internal/type_checkers.py |
index 2b3cd4de4c26926c67423059d584c85f788f65d9..f30ca6a80e165ce0bf8a2c2c08b2dec2d6b51ae9 100755 |
--- a/third_party/protobuf/python/google/protobuf/internal/type_checkers.py |
+++ b/third_party/protobuf/python/google/protobuf/internal/type_checkers.py |
@@ -1,6 +1,6 @@ |
# Protocol Buffers - Google's data interchange format |
# Copyright 2008 Google Inc. All rights reserved. |
-# http://code.google.com/p/protobuf/ |
+# https://developers.google.com/protocol-buffers/ |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions are |
@@ -45,6 +45,12 @@ TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization |
__author__ = 'robinson@google.com (Will Robinson)' |
+import six |
+ |
+if six.PY3: |
+ long = int |
+ |
+from google.protobuf.internal import api_implementation |
from google.protobuf.internal import decoder |
from google.protobuf.internal import encoder |
from google.protobuf.internal import wire_format |
@@ -52,22 +58,29 @@ from google.protobuf import descriptor |
_FieldDescriptor = descriptor.FieldDescriptor |
+def SupportsOpenEnums(field_descriptor): |
+ return field_descriptor.containing_type.syntax == "proto3" |
-def GetTypeChecker(cpp_type, field_type): |
+def GetTypeChecker(field): |
"""Returns a type checker for a message field of the specified types. |
Args: |
- cpp_type: C++ type of the field (see descriptor.py). |
- field_type: Protocol message field type (see descriptor.py). |
+ field: FieldDescriptor object for this field. |
Returns: |
An instance of TypeChecker which can be used to verify the types |
of values assigned to a field of the specified type. |
""" |
- if (cpp_type == _FieldDescriptor.CPPTYPE_STRING and |
- field_type == _FieldDescriptor.TYPE_STRING): |
+ if (field.cpp_type == _FieldDescriptor.CPPTYPE_STRING and |
+ field.type == _FieldDescriptor.TYPE_STRING): |
return UnicodeValueChecker() |
- return _VALUE_CHECKERS[cpp_type] |
+ if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM: |
+ if SupportsOpenEnums(field): |
+ # When open enums are supported, any int32 can be assigned. |
+ return _VALUE_CHECKERS[_FieldDescriptor.CPPTYPE_INT32] |
+ else: |
+ return EnumValueChecker(field.enum_type) |
+ return _VALUE_CHECKERS[field.cpp_type] |
# None of the typecheckers below make any attempt to guard against people |
@@ -85,10 +98,15 @@ class TypeChecker(object): |
self._acceptable_types = acceptable_types |
def CheckValue(self, proposed_value): |
+ """Type check the provided value and return it. |
+ |
+ The returned value might have been normalized to another type. |
+ """ |
if not isinstance(proposed_value, self._acceptable_types): |
message = ('%.1024r has type %s, but expected one of: %s' % |
(proposed_value, type(proposed_value), self._acceptable_types)) |
raise TypeError(message) |
+ return proposed_value |
# IntValueChecker and its subclasses perform integer type-checks |
@@ -98,34 +116,68 @@ class IntValueChecker(object): |
"""Checker used for integer fields. Performs type-check and range check.""" |
def CheckValue(self, proposed_value): |
- if not isinstance(proposed_value, (int, long)): |
+ if not isinstance(proposed_value, six.integer_types): |
message = ('%.1024r has type %s, but expected one of: %s' % |
- (proposed_value, type(proposed_value), (int, long))) |
+ (proposed_value, type(proposed_value), six.integer_types)) |
raise TypeError(message) |
if not self._MIN <= proposed_value <= self._MAX: |
raise ValueError('Value out of range: %d' % proposed_value) |
+ # We force 32-bit values to int and 64-bit values to long to make |
+ # alternate implementations where the distinction is more significant |
+ # (e.g. the C++ implementation) simpler. |
+ proposed_value = self._TYPE(proposed_value) |
+ return proposed_value |
+ |
+ def DefaultValue(self): |
+ return 0 |
+ |
+ |
+class EnumValueChecker(object): |
+ |
+ """Checker used for enum fields. Performs type-check and range check.""" |
+ |
+ def __init__(self, enum_type): |
+ self._enum_type = enum_type |
+ |
+ def CheckValue(self, proposed_value): |
+ if not isinstance(proposed_value, six.integer_types): |
+ message = ('%.1024r has type %s, but expected one of: %s' % |
+ (proposed_value, type(proposed_value), six.integer_types)) |
+ raise TypeError(message) |
+ if proposed_value not in self._enum_type.values_by_number: |
+ raise ValueError('Unknown enum value: %d' % proposed_value) |
+ return proposed_value |
+ |
+ def DefaultValue(self): |
+ return self._enum_type.values[0].number |
class UnicodeValueChecker(object): |
- """Checker used for string fields.""" |
+ """Checker used for string fields. |
+ |
+ Always returns a unicode value, even if the input is of type str. |
+ """ |
def CheckValue(self, proposed_value): |
- if not isinstance(proposed_value, (str, unicode)): |
+ if not isinstance(proposed_value, (bytes, six.text_type)): |
message = ('%.1024r has type %s, but expected one of: %s' % |
- (proposed_value, type(proposed_value), (str, unicode))) |
+ (proposed_value, type(proposed_value), (bytes, six.text_type))) |
raise TypeError(message) |
- # If the value is of type 'str' make sure that it is in 7-bit ASCII |
- # encoding. |
- if isinstance(proposed_value, str): |
+ # If the value is of type 'bytes' make sure that it is valid UTF-8 data. |
+ if isinstance(proposed_value, bytes): |
try: |
- unicode(proposed_value, 'ascii') |
+ proposed_value = proposed_value.decode('utf-8') |
except UnicodeDecodeError: |
- raise ValueError('%.1024r has type str, but isn\'t in 7-bit ASCII ' |
- 'encoding. Non-ASCII strings must be converted to ' |
+ raise ValueError('%.1024r has type bytes, but isn\'t valid UTF-8 ' |
+ 'encoding. Non-UTF-8 strings must be converted to ' |
'unicode objects before being added.' % |
(proposed_value)) |
+ return proposed_value |
+ |
+ def DefaultValue(self): |
+ return u"" |
class Int32ValueChecker(IntValueChecker): |
@@ -133,21 +185,25 @@ class Int32ValueChecker(IntValueChecker): |
# efficient. |
_MIN = -2147483648 |
_MAX = 2147483647 |
+ _TYPE = int |
class Uint32ValueChecker(IntValueChecker): |
_MIN = 0 |
_MAX = (1 << 32) - 1 |
+ _TYPE = int |
class Int64ValueChecker(IntValueChecker): |
_MIN = -(1 << 63) |
_MAX = (1 << 63) - 1 |
+ _TYPE = long |
class Uint64ValueChecker(IntValueChecker): |
_MIN = 0 |
_MAX = (1 << 64) - 1 |
+ _TYPE = long |
# Type-checkers for all scalar CPPTYPEs. |
@@ -161,8 +217,7 @@ _VALUE_CHECKERS = { |
_FieldDescriptor.CPPTYPE_FLOAT: TypeChecker( |
float, int, long), |
_FieldDescriptor.CPPTYPE_BOOL: TypeChecker(bool, int), |
- _FieldDescriptor.CPPTYPE_ENUM: Int32ValueChecker(), |
- _FieldDescriptor.CPPTYPE_STRING: TypeChecker(str), |
+ _FieldDescriptor.CPPTYPE_STRING: TypeChecker(bytes), |
} |