unknown_fields.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. # Protocol Buffers - Google's data interchange format
  2. # Copyright 2008 Google Inc. All rights reserved.
  3. #
  4. # Use of this source code is governed by a BSD-style
  5. # license that can be found in the LICENSE file or at
  6. # https://developers.google.com/open-source/licenses/bsd
  7. """Contains Unknown Fields APIs.
  8. Simple usage example:
  9. unknown_field_set = UnknownFieldSet(message)
  10. for unknown_field in unknown_field_set:
  11. wire_type = unknown_field.wire_type
  12. field_number = unknown_field.field_number
  13. data = unknown_field.data
  14. """
  15. from google.protobuf.internal import api_implementation
  16. if api_implementation._c_module is not None: # pylint: disable=protected-access
  17. UnknownFieldSet = api_implementation._c_module.UnknownFieldSet # pylint: disable=protected-access
  18. else:
  19. from google.protobuf.internal import decoder # pylint: disable=g-import-not-at-top
  20. from google.protobuf.internal import wire_format # pylint: disable=g-import-not-at-top
  21. class UnknownField:
  22. """A parsed unknown field."""
  23. # Disallows assignment to other attributes.
  24. __slots__ = ['_field_number', '_wire_type', '_data']
  25. def __init__(self, field_number, wire_type, data):
  26. self._field_number = field_number
  27. self._wire_type = wire_type
  28. self._data = data
  29. return
  30. @property
  31. def field_number(self):
  32. return self._field_number
  33. @property
  34. def wire_type(self):
  35. return self._wire_type
  36. @property
  37. def data(self):
  38. return self._data
  39. class UnknownFieldSet:
  40. """UnknownField container."""
  41. # Disallows assignment to other attributes.
  42. __slots__ = ['_values']
  43. def __init__(self, msg):
  44. def InternalAdd(field_number, wire_type, data):
  45. unknown_field = UnknownField(field_number, wire_type, data)
  46. self._values.append(unknown_field)
  47. self._values = []
  48. msg_des = msg.DESCRIPTOR
  49. # pylint: disable=protected-access
  50. unknown_fields = msg._unknown_fields
  51. if (msg_des.has_options and
  52. msg_des.GetOptions().message_set_wire_format):
  53. local_decoder = decoder.UnknownMessageSetItemDecoder()
  54. for _, buffer in unknown_fields:
  55. (field_number, data) = local_decoder(memoryview(buffer))
  56. InternalAdd(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED, data)
  57. else:
  58. for tag_bytes, buffer in unknown_fields:
  59. # pylint: disable=protected-access
  60. (tag, _) = decoder._DecodeVarint(tag_bytes, 0)
  61. field_number, wire_type = wire_format.UnpackTag(tag)
  62. if field_number == 0:
  63. raise RuntimeError('Field number 0 is illegal.')
  64. (data, _) = decoder._DecodeUnknownField(
  65. memoryview(buffer), 0, wire_type)
  66. InternalAdd(field_number, wire_type, data)
  67. def __getitem__(self, index):
  68. size = len(self._values)
  69. if index < 0:
  70. index += size
  71. if index < 0 or index >= size:
  72. raise IndexError('index %d out of range'.index)
  73. return self._values[index]
  74. def __len__(self):
  75. return len(self._values)
  76. def __iter__(self):
  77. return iter(self._values)