| Index: third_party/protobuf/python/google/protobuf/internal/well_known_types.py
|
| diff --git a/third_party/protobuf/python/google/protobuf/internal/well_known_types.py b/third_party/protobuf/python/google/protobuf/internal/well_known_types.py
|
| index 7c5dffd0fc53d4728647c1e8551aa9d676782c8d..d631abeeaa5d8368903a5e334fe9450d4fb0e8f1 100644
|
| --- a/third_party/protobuf/python/google/protobuf/internal/well_known_types.py
|
| +++ b/third_party/protobuf/python/google/protobuf/internal/well_known_types.py
|
| @@ -53,6 +53,7 @@ _NANOS_PER_MICROSECOND = 1000
|
| _MILLIS_PER_SECOND = 1000
|
| _MICROS_PER_SECOND = 1000000
|
| _SECONDS_PER_DAY = 24 * 3600
|
| +_DURATION_SECONDS_MAX = 315576000000
|
|
|
|
|
| class Error(Exception):
|
| @@ -247,6 +248,7 @@ class Duration(object):
|
| represent the exact Duration value. For example: "1s", "1.010s",
|
| "1.000000100s", "-3.100s"
|
| """
|
| + _CheckDurationValid(self.seconds, self.nanos)
|
| if self.seconds < 0 or self.nanos < 0:
|
| result = '-'
|
| seconds = - self.seconds + int((0 - self.nanos) // 1e9)
|
| @@ -286,14 +288,17 @@ class Duration(object):
|
| try:
|
| pos = value.find('.')
|
| if pos == -1:
|
| - self.seconds = int(value[:-1])
|
| - self.nanos = 0
|
| + seconds = int(value[:-1])
|
| + nanos = 0
|
| else:
|
| - self.seconds = int(value[:pos])
|
| + seconds = int(value[:pos])
|
| if value[0] == '-':
|
| - self.nanos = int(round(float('-0{0}'.format(value[pos: -1])) *1e9))
|
| + nanos = int(round(float('-0{0}'.format(value[pos: -1])) *1e9))
|
| else:
|
| - self.nanos = int(round(float('0{0}'.format(value[pos: -1])) *1e9))
|
| + nanos = int(round(float('0{0}'.format(value[pos: -1])) *1e9))
|
| + _CheckDurationValid(seconds, nanos)
|
| + self.seconds = seconds
|
| + self.nanos = nanos
|
| except ValueError:
|
| raise ParseError(
|
| 'Couldn\'t parse duration: {0}.'.format(value))
|
| @@ -359,6 +364,17 @@ class Duration(object):
|
| self.nanos = nanos
|
|
|
|
|
| +def _CheckDurationValid(seconds, nanos):
|
| + if seconds < -_DURATION_SECONDS_MAX or seconds > _DURATION_SECONDS_MAX:
|
| + raise Error(
|
| + 'Duration is not valid: Seconds {0} must be in range '
|
| + '[-315576000000, 315576000000].'.format(seconds))
|
| + if nanos <= -_NANOS_PER_SECOND or nanos >= _NANOS_PER_SECOND:
|
| + raise Error(
|
| + 'Duration is not valid: Nanos {0} must be in range '
|
| + '[-999999999, 999999999].'.format(nanos))
|
| +
|
| +
|
| def _RoundTowardZero(value, divider):
|
| """Truncates the remainder part after division."""
|
| # For some languanges, the sign of the remainder is implementation
|
| @@ -379,13 +395,16 @@ class FieldMask(object):
|
|
|
| def ToJsonString(self):
|
| """Converts FieldMask to string according to proto3 JSON spec."""
|
| - return ','.join(self.paths)
|
| + camelcase_paths = []
|
| + for path in self.paths:
|
| + camelcase_paths.append(_SnakeCaseToCamelCase(path))
|
| + return ','.join(camelcase_paths)
|
|
|
| def FromJsonString(self, value):
|
| """Converts string to FieldMask according to proto3 JSON spec."""
|
| self.Clear()
|
| for path in value.split(','):
|
| - self.paths.append(path)
|
| + self.paths.append(_CamelCaseToSnakeCase(path))
|
|
|
| def IsValidForDescriptor(self, message_descriptor):
|
| """Checks whether the FieldMask is valid for Message Descriptor."""
|
| @@ -472,6 +491,48 @@ def _CheckFieldMaskMessage(message):
|
| message_descriptor.full_name))
|
|
|
|
|
| +def _SnakeCaseToCamelCase(path_name):
|
| + """Converts a path name from snake_case to camelCase."""
|
| + result = []
|
| + after_underscore = False
|
| + for c in path_name:
|
| + if c.isupper():
|
| + raise Error('Fail to print FieldMask to Json string: Path name '
|
| + '{0} must not contain uppercase letters.'.format(path_name))
|
| + if after_underscore:
|
| + if c.islower():
|
| + result.append(c.upper())
|
| + after_underscore = False
|
| + else:
|
| + raise Error('Fail to print FieldMask to Json string: The '
|
| + 'character after a "_" must be a lowercase letter '
|
| + 'in path name {0}.'.format(path_name))
|
| + elif c == '_':
|
| + after_underscore = True
|
| + else:
|
| + result += c
|
| +
|
| + if after_underscore:
|
| + raise Error('Fail to print FieldMask to Json string: Trailing "_" '
|
| + 'in path name {0}.'.format(path_name))
|
| + return ''.join(result)
|
| +
|
| +
|
| +def _CamelCaseToSnakeCase(path_name):
|
| + """Converts a field name from camelCase to snake_case."""
|
| + result = []
|
| + for c in path_name:
|
| + if c == '_':
|
| + raise ParseError('Fail to parse FieldMask: Path name '
|
| + '{0} must not contain "_"s.'.format(path_name))
|
| + if c.isupper():
|
| + result += '_'
|
| + result += c.lower()
|
| + else:
|
| + result += c
|
| + return ''.join(result)
|
| +
|
| +
|
| class _FieldMaskTree(object):
|
| """Represents a FieldMask in a tree structure.
|
|
|
|
|