ruby_memprofiler_pprof 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. checksums.yaml +7 -0
  2. data/ext/ruby_memprofiler_pprof/backtrace.c +429 -0
  3. data/ext/ruby_memprofiler_pprof/collector.c +1055 -0
  4. data/ext/ruby_memprofiler_pprof/compat.c +182 -0
  5. data/ext/ruby_memprofiler_pprof/extconf.rb +72 -0
  6. data/ext/ruby_memprofiler_pprof/pprof.upb.c +170 -0
  7. data/ext/ruby_memprofiler_pprof/pprof.upb.h +848 -0
  8. data/ext/ruby_memprofiler_pprof/pprof_out.c +285 -0
  9. data/ext/ruby_memprofiler_pprof/ruby_memprofiler_pprof.c +11 -0
  10. data/ext/ruby_memprofiler_pprof/ruby_memprofiler_pprof.h +301 -0
  11. data/ext/ruby_memprofiler_pprof/strtab.c +391 -0
  12. data/ext/ruby_memprofiler_pprof/vendor/upb/BUILD +719 -0
  13. data/ext/ruby_memprofiler_pprof/vendor/upb/CONTRIBUTING.md +37 -0
  14. data/ext/ruby_memprofiler_pprof/vendor/upb/DESIGN.md +201 -0
  15. data/ext/ruby_memprofiler_pprof/vendor/upb/LICENSE +26 -0
  16. data/ext/ruby_memprofiler_pprof/vendor/upb/README.md +78 -0
  17. data/ext/ruby_memprofiler_pprof/vendor/upb/WORKSPACE +58 -0
  18. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/BUILD +53 -0
  19. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/amalgamate.py +129 -0
  20. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/build_defs.bzl +160 -0
  21. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/lua.BUILD +127 -0
  22. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/protobuf.patch +54 -0
  23. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/py_proto_library.bzl +137 -0
  24. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/python_downloads.bzl +84 -0
  25. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/system_python.bzl +101 -0
  26. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/upb_proto_library.bzl +388 -0
  27. data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/workspace_deps.bzl +89 -0
  28. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/BUILD +252 -0
  29. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/BUILD.googleapis +54 -0
  30. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/benchmark.cc +333 -0
  31. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/build_defs.bzl +88 -0
  32. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/compare.py +118 -0
  33. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/descriptor.proto +888 -0
  34. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/descriptor_sv.proto +890 -0
  35. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/empty.proto +6 -0
  36. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/gen_protobuf_binary_cc.py +64 -0
  37. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/gen_synthetic_protos.py +118 -0
  38. data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/gen_upb_binary_c.py +65 -0
  39. data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/BUILD.bazel +102 -0
  40. data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/README.md +23 -0
  41. data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/build_defs.bzl +73 -0
  42. data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/make_cmakelists.py +340 -0
  43. data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/staleness_test.py +57 -0
  44. data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/staleness_test_lib.py +186 -0
  45. data/ext/ruby_memprofiler_pprof/vendor/upb/docs/render.py +43 -0
  46. data/ext/ruby_memprofiler_pprof/vendor/upb/docs/style-guide.md +65 -0
  47. data/ext/ruby_memprofiler_pprof/vendor/upb/docs/vs-cpp-protos.md +255 -0
  48. data/ext/ruby_memprofiler_pprof/vendor/upb/docs/wrapping-upb.md +444 -0
  49. data/ext/ruby_memprofiler_pprof/vendor/upb/python/BUILD +216 -0
  50. data/ext/ruby_memprofiler_pprof/vendor/upb/python/convert.c +394 -0
  51. data/ext/ruby_memprofiler_pprof/vendor/upb/python/convert.h +63 -0
  52. data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor.c +1694 -0
  53. data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor.h +80 -0
  54. data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor_containers.c +704 -0
  55. data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor_containers.h +114 -0
  56. data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor_pool.c +650 -0
  57. data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor_pool.h +48 -0
  58. data/ext/ruby_memprofiler_pprof/vendor/upb/python/dist/BUILD.bazel +193 -0
  59. data/ext/ruby_memprofiler_pprof/vendor/upb/python/dist/dist.bzl +190 -0
  60. data/ext/ruby_memprofiler_pprof/vendor/upb/python/extension_dict.c +247 -0
  61. data/ext/ruby_memprofiler_pprof/vendor/upb/python/extension_dict.h +39 -0
  62. data/ext/ruby_memprofiler_pprof/vendor/upb/python/map.c +522 -0
  63. data/ext/ruby_memprofiler_pprof/vendor/upb/python/map.h +66 -0
  64. data/ext/ruby_memprofiler_pprof/vendor/upb/python/message.c +1909 -0
  65. data/ext/ruby_memprofiler_pprof/vendor/upb/python/message.h +101 -0
  66. data/ext/ruby_memprofiler_pprof/vendor/upb/python/minimal_test.py +183 -0
  67. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/BUILD +70 -0
  68. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/README.md +11 -0
  69. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/descriptor_database_test_wrapper.py +30 -0
  70. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/descriptor_pool_test_wrapper.py +45 -0
  71. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/descriptor_test_wrapper.py +46 -0
  72. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/generator_test_wrapper.py +30 -0
  73. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/json_format_test_wrapper.py +30 -0
  74. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/keywords_test_wrapper.py +30 -0
  75. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/message_factory_test_wrapper.py +37 -0
  76. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/message_test_wrapper.py +52 -0
  77. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/proto_builder_test_wrapper.py +32 -0
  78. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/pyproto_test_wrapper.bzl +36 -0
  79. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/reflection_test_wrapper.py +45 -0
  80. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/service_reflection_test_wrapper.py +30 -0
  81. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/symbol_database_test_wrapper.py +30 -0
  82. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/text_encoding_test_wrapper.py +30 -0
  83. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/text_format_test_wrapper.py +30 -0
  84. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/unknown_fields_test_wrapper.py +30 -0
  85. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/well_known_types_test_wrapper.py +36 -0
  86. data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/wire_format_test_wrapper.py +30 -0
  87. data/ext/ruby_memprofiler_pprof/vendor/upb/python/protobuf.c +350 -0
  88. data/ext/ruby_memprofiler_pprof/vendor/upb/python/protobuf.h +230 -0
  89. data/ext/ruby_memprofiler_pprof/vendor/upb/python/py_extension.bzl +55 -0
  90. data/ext/ruby_memprofiler_pprof/vendor/upb/python/python_api.h +61 -0
  91. data/ext/ruby_memprofiler_pprof/vendor/upb/python/repeated.c +828 -0
  92. data/ext/ruby_memprofiler_pprof/vendor/upb/python/repeated.h +69 -0
  93. data/ext/ruby_memprofiler_pprof/vendor/upb/python/unknown_fields.c +404 -0
  94. data/ext/ruby_memprofiler_pprof/vendor/upb/python/unknown_fields.h +39 -0
  95. data/ext/ruby_memprofiler_pprof/vendor/upb/python/version_script.lds +6 -0
  96. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/lunit/LICENSE +32 -0
  97. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/lunit/README.google +9 -0
  98. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/lunit/console.lua +156 -0
  99. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/lunit/lunit.lua +725 -0
  100. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/BUILD +19 -0
  101. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/LICENSE +21 -0
  102. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/naive.c +92 -0
  103. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/range2-neon.c +157 -0
  104. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/range2-sse.c +170 -0
  105. data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/utf8_range.h +9 -0
  106. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/BUILD.bazel +129 -0
  107. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/README.md +8 -0
  108. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/def.c +939 -0
  109. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/lua_proto_library.bzl +138 -0
  110. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/main.c +83 -0
  111. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/msg.c +1118 -0
  112. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/test.proto +69 -0
  113. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/test_upb.lua +846 -0
  114. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/upb.c +258 -0
  115. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/upb.h +132 -0
  116. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/upb.lua +58 -0
  117. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/upbc.cc +134 -0
  118. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/collections.c +192 -0
  119. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/collections.h +174 -0
  120. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/conformance_upb.c +346 -0
  121. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/conformance_upb_failures.txt +1 -0
  122. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/decode.c +1221 -0
  123. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/decode.h +94 -0
  124. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/decode_fast.c +1055 -0
  125. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/decode_fast.h +153 -0
  126. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/decode_internal.h +211 -0
  127. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/def.c +3262 -0
  128. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/def.h +414 -0
  129. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/def.hpp +438 -0
  130. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/empty.proto +1 -0
  131. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/encode.c +604 -0
  132. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/encode.h +71 -0
  133. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/fuzz/BUILD +13 -0
  134. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/fuzz/file_descriptor_parsenew_fuzzer.cc +43 -0
  135. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/json_decode.c +1509 -0
  136. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/json_decode.h +47 -0
  137. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/json_encode.c +776 -0
  138. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/json_encode.h +62 -0
  139. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table.c +1147 -0
  140. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table.h +189 -0
  141. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table.hpp +112 -0
  142. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table_accessors.c +363 -0
  143. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table_accessors.h +263 -0
  144. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table_accessors_internal.h +59 -0
  145. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table_accessors_test.cc +425 -0
  146. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table_test.cc +230 -0
  147. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/msg.c +428 -0
  148. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/msg.h +114 -0
  149. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/msg_internal.h +836 -0
  150. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/msg_test.cc +491 -0
  151. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/msg_test.proto +195 -0
  152. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/port_def.inc +261 -0
  153. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/port_undef.inc +62 -0
  154. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/reflection.c +323 -0
  155. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/reflection.h +109 -0
  156. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/reflection.hpp +37 -0
  157. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/table.c +926 -0
  158. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/table_internal.h +385 -0
  159. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/test.proto +74 -0
  160. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/test_cpp.cc +186 -0
  161. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/test_cpp.proto +12 -0
  162. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/test_generated_code.cc +977 -0
  163. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/test_table.cc +580 -0
  164. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/text_encode.c +472 -0
  165. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/text_encode.h +64 -0
  166. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/upb.c +362 -0
  167. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/upb.h +378 -0
  168. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/upb.hpp +115 -0
  169. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/upb_internal.h +68 -0
  170. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/BUILD +121 -0
  171. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/README.md +7 -0
  172. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/compare.c +300 -0
  173. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/compare.h +66 -0
  174. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/compare_test.cc +236 -0
  175. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto.c +572 -0
  176. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto.h +62 -0
  177. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_public_import_test.proto +32 -0
  178. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_regular_import_test.proto +36 -0
  179. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_test.cc +143 -0
  180. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_test.proto +119 -0
  181. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_weak_import_test.proto +28 -0
  182. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_wweak_import_test.proto +28 -0
  183. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/required_fields.c +311 -0
  184. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/required_fields.h +94 -0
  185. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/required_fields_test.cc +202 -0
  186. data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/required_fields_test.proto +48 -0
  187. data/ext/ruby_memprofiler_pprof/vendor/upb/upbc/BUILD +78 -0
  188. data/ext/ruby_memprofiler_pprof/vendor/upb/upbc/common.cc +77 -0
  189. data/ext/ruby_memprofiler_pprof/vendor/upb/upbc/common.h +112 -0
  190. data/ext/ruby_memprofiler_pprof/vendor/upb/upbc/protoc-gen-upb.cc +1997 -0
  191. data/ext/ruby_memprofiler_pprof/vendor/upb/upbc/protoc-gen-upbdefs.cc +193 -0
  192. data/lib/ruby_memprofiler_pprof/atfork.rb +77 -0
  193. data/lib/ruby_memprofiler_pprof/block_flusher.rb +61 -0
  194. data/lib/ruby_memprofiler_pprof/file_flusher.rb +45 -0
  195. data/lib/ruby_memprofiler_pprof/profile_app.rb +30 -0
  196. data/lib/ruby_memprofiler_pprof/profile_data.rb +18 -0
  197. data/lib/ruby_memprofiler_pprof/version.rb +5 -0
  198. data/lib/ruby_memprofiler_pprof.rb +8 -0
  199. data/libexec/ruby_memprofiler_pprof_profile +16 -0
  200. metadata +257 -0
@@ -0,0 +1,522 @@
1
+ /*
2
+ * Copyright (c) 2009-2021, Google LLC
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ * * Redistributions of source code must retain the above copyright
8
+ * notice, this list of conditions and the following disclaimer.
9
+ * * Redistributions in binary form must reproduce the above copyright
10
+ * notice, this list of conditions and the following disclaimer in the
11
+ * documentation and/or other materials provided with the distribution.
12
+ * * Neither the name of Google LLC nor the
13
+ * names of its contributors may be used to endorse or promote products
14
+ * derived from this software without specific prior written permission.
15
+ *
16
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
20
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ */
27
+
28
+ #include "python/map.h"
29
+
30
+ #include "python/convert.h"
31
+ #include "python/message.h"
32
+ #include "python/protobuf.h"
33
+ #include "upb/collections.h"
34
+
35
+ // -----------------------------------------------------------------------------
36
+ // MapContainer
37
+ // -----------------------------------------------------------------------------
38
+
39
+ typedef struct {
40
+ PyObject_HEAD;
41
+ PyObject* arena;
42
+ // The field descriptor (upb_FieldDef*).
43
+ // The low bit indicates whether the container is reified (see ptr below).
44
+ // - low bit set: repeated field is a stub (empty map, no underlying data).
45
+ // - low bit clear: repeated field is reified (points to upb_Array).
46
+ uintptr_t field;
47
+ union {
48
+ PyObject* parent; // stub: owning pointer to parent message.
49
+ upb_Map* map; // reified: the data for this array.
50
+ } ptr;
51
+ int version;
52
+ } PyUpb_MapContainer;
53
+
54
+ static PyObject* PyUpb_MapIterator_New(PyUpb_MapContainer* map);
55
+
56
+ static bool PyUpb_MapContainer_IsStub(PyUpb_MapContainer* self) {
57
+ return self->field & 1;
58
+ }
59
+
60
+ // If the map is reified, returns it. Otherwise, returns NULL.
61
+ // If NULL is returned, the object is empty and has no underlying data.
62
+ static upb_Map* PyUpb_MapContainer_GetIfReified(PyUpb_MapContainer* self) {
63
+ return PyUpb_MapContainer_IsStub(self) ? NULL : self->ptr.map;
64
+ }
65
+
66
+ static const upb_FieldDef* PyUpb_MapContainer_GetField(
67
+ PyUpb_MapContainer* self) {
68
+ return (const upb_FieldDef*)(self->field & ~(uintptr_t)1);
69
+ }
70
+
71
+ static void PyUpb_MapContainer_Dealloc(void* _self) {
72
+ PyUpb_MapContainer* self = _self;
73
+ Py_DECREF(self->arena);
74
+ if (PyUpb_MapContainer_IsStub(self)) {
75
+ PyUpb_CMessage_CacheDelete(self->ptr.parent,
76
+ PyUpb_MapContainer_GetField(self));
77
+ Py_DECREF(self->ptr.parent);
78
+ } else {
79
+ PyUpb_ObjCache_Delete(self->ptr.map);
80
+ }
81
+ PyUpb_Dealloc(_self);
82
+ }
83
+
84
+ PyTypeObject* PyUpb_MapContainer_GetClass(const upb_FieldDef* f) {
85
+ assert(upb_FieldDef_IsMap(f));
86
+ PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
87
+ return upb_FieldDef_IsSubMessage(f) ? state->message_map_container_type
88
+ : state->scalar_map_container_type;
89
+ }
90
+
91
+ PyObject* PyUpb_MapContainer_NewStub(PyObject* parent, const upb_FieldDef* f,
92
+ PyObject* arena) {
93
+ // We only create stubs when the parent is reified, by convention. However
94
+ // this is not an invariant: the parent could become reified at any time.
95
+ assert(PyUpb_CMessage_GetIfReified(parent) == NULL);
96
+ PyTypeObject* cls = PyUpb_MapContainer_GetClass(f);
97
+ PyUpb_MapContainer* map = (void*)PyType_GenericAlloc(cls, 0);
98
+ map->arena = arena;
99
+ map->field = (uintptr_t)f | 1;
100
+ map->ptr.parent = parent;
101
+ map->version = 0;
102
+ Py_INCREF(arena);
103
+ Py_INCREF(parent);
104
+ return &map->ob_base;
105
+ }
106
+
107
+ void PyUpb_MapContainer_Reify(PyObject* _self, upb_Map* map) {
108
+ PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
109
+ if (!map) {
110
+ const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
111
+ upb_Arena* arena = PyUpb_Arena_Get(self->arena);
112
+ const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
113
+ const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
114
+ const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1);
115
+ map = upb_Map_New(arena, upb_FieldDef_CType(key_f),
116
+ upb_FieldDef_CType(val_f));
117
+ }
118
+ PyUpb_ObjCache_Add(map, &self->ob_base);
119
+ Py_DECREF(self->ptr.parent);
120
+ self->ptr.map = map; // Overwrites self->ptr.parent.
121
+ self->field &= ~(uintptr_t)1;
122
+ assert(!PyUpb_MapContainer_IsStub(self));
123
+ }
124
+
125
+ void PyUpb_MapContainer_Invalidate(PyObject* obj) {
126
+ PyUpb_MapContainer* self = (PyUpb_MapContainer*)obj;
127
+ self->version++;
128
+ }
129
+
130
+ upb_Map* PyUpb_MapContainer_EnsureReified(PyObject* _self) {
131
+ PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
132
+ self->version++;
133
+ upb_Map* map = PyUpb_MapContainer_GetIfReified(self);
134
+ if (map) return map; // Already writable.
135
+
136
+ const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
137
+ upb_Arena* arena = PyUpb_Arena_Get(self->arena);
138
+ const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
139
+ const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
140
+ const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1);
141
+ map =
142
+ upb_Map_New(arena, upb_FieldDef_CType(key_f), upb_FieldDef_CType(val_f));
143
+ upb_MessageValue msgval = {.map_val = map};
144
+ PyUpb_CMessage_SetConcreteSubobj(self->ptr.parent, f, msgval);
145
+ PyUpb_MapContainer_Reify((PyObject*)self, map);
146
+ return map;
147
+ }
148
+
149
+ bool PyUpb_MapContainer_Set(PyUpb_MapContainer* self, upb_Map* map,
150
+ upb_MessageValue key, upb_MessageValue val,
151
+ upb_Arena* arena) {
152
+ switch (upb_Map_Insert(map, key, val, arena)) {
153
+ case kUpb_MapInsertStatus_Inserted:
154
+ return true;
155
+ case kUpb_MapInsertStatus_Replaced:
156
+ // We did not insert a new key, undo the previous invalidate.
157
+ self->version--;
158
+ return true;
159
+ case kUpb_MapInsertStatus_OutOfMemory:
160
+ return false;
161
+ }
162
+ }
163
+
164
+ int PyUpb_MapContainer_AssignSubscript(PyObject* _self, PyObject* key,
165
+ PyObject* val) {
166
+ PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
167
+ upb_Map* map = PyUpb_MapContainer_EnsureReified(_self);
168
+ const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
169
+ const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
170
+ const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
171
+ const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1);
172
+ upb_Arena* arena = PyUpb_Arena_Get(self->arena);
173
+ upb_MessageValue u_key, u_val;
174
+ if (!PyUpb_PyToUpb(key, key_f, &u_key, arena)) return -1;
175
+
176
+ if (val) {
177
+ if (!PyUpb_PyToUpb(val, val_f, &u_val, arena)) return -1;
178
+ if (!PyUpb_MapContainer_Set(self, map, u_key, u_val, arena)) return -1;
179
+ } else {
180
+ if (!upb_Map_Delete(map, u_key)) {
181
+ PyErr_Format(PyExc_KeyError, "Key not present in map");
182
+ return -1;
183
+ }
184
+ }
185
+ return 0;
186
+ }
187
+
188
+ PyObject* PyUpb_MapContainer_Subscript(PyObject* _self, PyObject* key) {
189
+ PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
190
+ upb_Map* map = PyUpb_MapContainer_GetIfReified(self);
191
+ const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
192
+ const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
193
+ const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
194
+ const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1);
195
+ upb_Arena* arena = PyUpb_Arena_Get(self->arena);
196
+ upb_MessageValue u_key, u_val;
197
+ if (!PyUpb_PyToUpb(key, key_f, &u_key, arena)) return NULL;
198
+ if (!map || !upb_Map_Get(map, u_key, &u_val)) {
199
+ map = PyUpb_MapContainer_EnsureReified(_self);
200
+ upb_Arena* arena = PyUpb_Arena_Get(self->arena);
201
+ if (upb_FieldDef_IsSubMessage(val_f)) {
202
+ u_val.msg_val = upb_Message_New(upb_FieldDef_MessageSubDef(val_f), arena);
203
+ } else {
204
+ memset(&u_val, 0, sizeof(u_val));
205
+ }
206
+ if (!PyUpb_MapContainer_Set(self, map, u_key, u_val, arena)) return false;
207
+ }
208
+ return PyUpb_UpbToPy(u_val, val_f, self->arena);
209
+ }
210
+
211
+ PyObject* PyUpb_MapContainer_Contains(PyObject* _self, PyObject* key) {
212
+ PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
213
+ upb_Map* map = PyUpb_MapContainer_GetIfReified(self);
214
+ if (!map) Py_RETURN_FALSE;
215
+ const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
216
+ const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
217
+ const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
218
+ upb_MessageValue u_key;
219
+ if (!PyUpb_PyToUpb(key, key_f, &u_key, NULL)) return NULL;
220
+ if (upb_Map_Get(map, u_key, NULL)) {
221
+ Py_RETURN_TRUE;
222
+ } else {
223
+ Py_RETURN_FALSE;
224
+ }
225
+ }
226
+
227
+ PyObject* PyUpb_MapContainer_Clear(PyObject* _self, PyObject* key) {
228
+ upb_Map* map = PyUpb_MapContainer_EnsureReified(_self);
229
+ upb_Map_Clear(map);
230
+ Py_RETURN_NONE;
231
+ }
232
+
233
+ static PyObject* PyUpb_MapContainer_Get(PyObject* _self, PyObject* args,
234
+ PyObject* kwargs) {
235
+ PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
236
+ static const char* kwlist[] = {"key", "default", NULL};
237
+ PyObject* key;
238
+ PyObject* default_value = NULL;
239
+ upb_Map* map = PyUpb_MapContainer_GetIfReified(self);
240
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", (char**)kwlist, &key,
241
+ &default_value)) {
242
+ return NULL;
243
+ }
244
+
245
+ const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
246
+ const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
247
+ const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
248
+ const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1);
249
+ upb_Arena* arena = PyUpb_Arena_Get(self->arena);
250
+ upb_MessageValue u_key, u_val;
251
+ if (!PyUpb_PyToUpb(key, key_f, &u_key, arena)) return NULL;
252
+ if (map && upb_Map_Get(map, u_key, &u_val)) {
253
+ return PyUpb_UpbToPy(u_val, val_f, self->arena);
254
+ }
255
+ if (default_value) {
256
+ Py_INCREF(default_value);
257
+ return default_value;
258
+ }
259
+ Py_RETURN_NONE;
260
+ }
261
+
262
+ static PyObject* PyUpb_MapContainer_GetEntryClass(PyObject* _self,
263
+ PyObject* arg) {
264
+ PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
265
+ const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
266
+ const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
267
+ return PyUpb_Descriptor_GetClass(entry_m);
268
+ }
269
+
270
+ Py_ssize_t PyUpb_MapContainer_Length(PyObject* _self) {
271
+ PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
272
+ upb_Map* map = PyUpb_MapContainer_GetIfReified(self);
273
+ return map ? upb_Map_Size(map) : 0;
274
+ }
275
+
276
+ PyUpb_MapContainer* PyUpb_MapContainer_Check(PyObject* _self) {
277
+ PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
278
+ if (!PyObject_TypeCheck(_self, state->message_map_container_type) &&
279
+ !PyObject_TypeCheck(_self, state->scalar_map_container_type)) {
280
+ PyErr_Format(PyExc_TypeError, "Expected protobuf map, but got %R", _self);
281
+ return NULL;
282
+ }
283
+ return (PyUpb_MapContainer*)_self;
284
+ }
285
+
286
+ int PyUpb_CMessage_InitMapAttributes(PyObject* map, PyObject* value,
287
+ const upb_FieldDef* f);
288
+
289
+ static PyObject* PyUpb_MapContainer_MergeFrom(PyObject* _self, PyObject* _arg) {
290
+ PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
291
+ const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
292
+
293
+ if (PyDict_Check(_arg)) {
294
+ return PyErr_Format(PyExc_AttributeError, "Merging of dict is not allowed");
295
+ }
296
+
297
+ if (PyUpb_CMessage_InitMapAttributes(_self, _arg, f) < 0) {
298
+ return NULL;
299
+ }
300
+
301
+ Py_RETURN_NONE;
302
+ }
303
+
304
+ static PyObject* PyUpb_MapContainer_Repr(PyObject* _self) {
305
+ PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
306
+ upb_Map* map = PyUpb_MapContainer_GetIfReified(self);
307
+ PyObject* dict = PyDict_New();
308
+ if (map) {
309
+ const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
310
+ const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
311
+ const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
312
+ const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1);
313
+ size_t iter = kUpb_Map_Begin;
314
+ while (upb_MapIterator_Next(map, &iter)) {
315
+ PyObject* key =
316
+ PyUpb_UpbToPy(upb_MapIterator_Key(map, iter), key_f, self->arena);
317
+ PyObject* val =
318
+ PyUpb_UpbToPy(upb_MapIterator_Value(map, iter), val_f, self->arena);
319
+ if (!key || !val) {
320
+ Py_XDECREF(key);
321
+ Py_XDECREF(val);
322
+ Py_DECREF(dict);
323
+ return NULL;
324
+ }
325
+ PyDict_SetItem(dict, key, val);
326
+ Py_DECREF(key);
327
+ Py_DECREF(val);
328
+ }
329
+ }
330
+ PyObject* repr = PyObject_Repr(dict);
331
+ Py_DECREF(dict);
332
+ return repr;
333
+ }
334
+
335
+ PyObject* PyUpb_MapContainer_GetOrCreateWrapper(upb_Map* map,
336
+ const upb_FieldDef* f,
337
+ PyObject* arena) {
338
+ PyUpb_MapContainer* ret = (void*)PyUpb_ObjCache_Get(map);
339
+ if (ret) return &ret->ob_base;
340
+
341
+ PyTypeObject* cls = PyUpb_MapContainer_GetClass(f);
342
+ ret = (void*)PyType_GenericAlloc(cls, 0);
343
+ ret->arena = arena;
344
+ ret->field = (uintptr_t)f;
345
+ ret->ptr.map = map;
346
+ ret->version = 0;
347
+ Py_INCREF(arena);
348
+ PyUpb_ObjCache_Add(map, &ret->ob_base);
349
+ return &ret->ob_base;
350
+ }
351
+
352
+ // -----------------------------------------------------------------------------
353
+ // ScalarMapContainer
354
+ // -----------------------------------------------------------------------------
355
+
356
+ static PyMethodDef PyUpb_ScalarMapContainer_Methods[] = {
357
+ {"__contains__", PyUpb_MapContainer_Contains, METH_O,
358
+ "Tests whether a key is a member of the map."},
359
+ {"clear", PyUpb_MapContainer_Clear, METH_NOARGS,
360
+ "Removes all elements from the map."},
361
+ {"get", (PyCFunction)PyUpb_MapContainer_Get, METH_VARARGS | METH_KEYWORDS,
362
+ "Gets the value for the given key if present, or otherwise a default"},
363
+ {"GetEntryClass", PyUpb_MapContainer_GetEntryClass, METH_NOARGS,
364
+ "Return the class used to build Entries of (key, value) pairs."},
365
+ {"MergeFrom", PyUpb_MapContainer_MergeFrom, METH_O,
366
+ "Merges a map into the current map."},
367
+ /*
368
+ { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
369
+ "Makes a deep copy of the class." },
370
+ { "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
371
+ "Outputs picklable representation of the repeated field." },
372
+ */
373
+ {NULL, NULL},
374
+ };
375
+
376
+ static PyType_Slot PyUpb_ScalarMapContainer_Slots[] = {
377
+ {Py_tp_dealloc, PyUpb_MapContainer_Dealloc},
378
+ {Py_mp_length, PyUpb_MapContainer_Length},
379
+ {Py_mp_subscript, PyUpb_MapContainer_Subscript},
380
+ {Py_mp_ass_subscript, PyUpb_MapContainer_AssignSubscript},
381
+ {Py_tp_methods, PyUpb_ScalarMapContainer_Methods},
382
+ {Py_tp_iter, PyUpb_MapIterator_New},
383
+ {Py_tp_repr, PyUpb_MapContainer_Repr},
384
+ {Py_tp_hash, PyObject_HashNotImplemented},
385
+ {0, NULL},
386
+ };
387
+
388
+ static PyType_Spec PyUpb_ScalarMapContainer_Spec = {
389
+ PYUPB_MODULE_NAME ".ScalarMapContainer",
390
+ sizeof(PyUpb_MapContainer),
391
+ 0,
392
+ Py_TPFLAGS_DEFAULT,
393
+ PyUpb_ScalarMapContainer_Slots,
394
+ };
395
+
396
+ // -----------------------------------------------------------------------------
397
+ // MessageMapContainer
398
+ // -----------------------------------------------------------------------------
399
+
400
+ static PyMethodDef PyUpb_MessageMapContainer_Methods[] = {
401
+ {"__contains__", PyUpb_MapContainer_Contains, METH_O,
402
+ "Tests whether the map contains this element."},
403
+ {"clear", PyUpb_MapContainer_Clear, METH_NOARGS,
404
+ "Removes all elements from the map."},
405
+ {"get", (PyCFunction)PyUpb_MapContainer_Get, METH_VARARGS | METH_KEYWORDS,
406
+ "Gets the value for the given key if present, or otherwise a default"},
407
+ {"get_or_create", PyUpb_MapContainer_Subscript, METH_O,
408
+ "Alias for getitem, useful to make explicit that the map is mutated."},
409
+ {"GetEntryClass", PyUpb_MapContainer_GetEntryClass, METH_NOARGS,
410
+ "Return the class used to build Entries of (key, value) pairs."},
411
+ {"MergeFrom", PyUpb_MapContainer_MergeFrom, METH_O,
412
+ "Merges a map into the current map."},
413
+ /*
414
+ { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
415
+ "Makes a deep copy of the class." },
416
+ { "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
417
+ "Outputs picklable representation of the repeated field." },
418
+ */
419
+ {NULL, NULL},
420
+ };
421
+
422
+ static PyType_Slot PyUpb_MessageMapContainer_Slots[] = {
423
+ {Py_tp_dealloc, PyUpb_MapContainer_Dealloc},
424
+ {Py_mp_length, PyUpb_MapContainer_Length},
425
+ {Py_mp_subscript, PyUpb_MapContainer_Subscript},
426
+ {Py_mp_ass_subscript, PyUpb_MapContainer_AssignSubscript},
427
+ {Py_tp_methods, PyUpb_MessageMapContainer_Methods},
428
+ {Py_tp_iter, PyUpb_MapIterator_New},
429
+ {Py_tp_repr, PyUpb_MapContainer_Repr},
430
+ {Py_tp_hash, PyObject_HashNotImplemented},
431
+ {0, NULL}};
432
+
433
+ static PyType_Spec PyUpb_MessageMapContainer_Spec = {
434
+ PYUPB_MODULE_NAME ".MessageMapContainer", sizeof(PyUpb_MapContainer), 0,
435
+ Py_TPFLAGS_DEFAULT, PyUpb_MessageMapContainer_Slots};
436
+
437
+ // -----------------------------------------------------------------------------
438
+ // MapIterator
439
+ // -----------------------------------------------------------------------------
440
+
441
+ typedef struct {
442
+ PyObject_HEAD;
443
+ PyUpb_MapContainer* map; // We own a reference.
444
+ size_t iter;
445
+ int version;
446
+ } PyUpb_MapIterator;
447
+
448
+ static PyObject* PyUpb_MapIterator_New(PyUpb_MapContainer* map) {
449
+ PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
450
+ PyUpb_MapIterator* iter =
451
+ (void*)PyType_GenericAlloc(state->map_iterator_type, 0);
452
+ iter->map = map;
453
+ iter->iter = kUpb_Map_Begin;
454
+ iter->version = map->version;
455
+ Py_INCREF(map);
456
+ return &iter->ob_base;
457
+ }
458
+
459
+ static void PyUpb_MapIterator_Dealloc(void* _self) {
460
+ PyUpb_MapIterator* self = (PyUpb_MapIterator*)_self;
461
+ Py_DECREF(&self->map->ob_base);
462
+ PyUpb_Dealloc(_self);
463
+ }
464
+
465
+ PyObject* PyUpb_MapIterator_IterNext(PyObject* _self) {
466
+ PyUpb_MapIterator* self = (PyUpb_MapIterator*)_self;
467
+ if (self->version != self->map->version) {
468
+ return PyErr_Format(PyExc_RuntimeError, "Map modified during iteration.");
469
+ }
470
+ upb_Map* map = PyUpb_MapContainer_GetIfReified(self->map);
471
+ if (!map) return NULL;
472
+ if (!upb_MapIterator_Next(map, &self->iter)) return NULL;
473
+ upb_MessageValue key = upb_MapIterator_Key(map, self->iter);
474
+ const upb_FieldDef* f = PyUpb_MapContainer_GetField(self->map);
475
+ const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
476
+ const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
477
+ return PyUpb_UpbToPy(key, key_f, self->map->arena);
478
+ }
479
+
480
+ static PyType_Slot PyUpb_MapIterator_Slots[] = {
481
+ {Py_tp_dealloc, PyUpb_MapIterator_Dealloc},
482
+ {Py_tp_iter, PyObject_SelfIter},
483
+ {Py_tp_iternext, PyUpb_MapIterator_IterNext},
484
+ {0, NULL}};
485
+
486
+ static PyType_Spec PyUpb_MapIterator_Spec = {
487
+ PYUPB_MODULE_NAME ".MapIterator", sizeof(PyUpb_MapIterator), 0,
488
+ Py_TPFLAGS_DEFAULT, PyUpb_MapIterator_Slots};
489
+
490
+ // -----------------------------------------------------------------------------
491
+ // Top Level
492
+ // -----------------------------------------------------------------------------
493
+
494
+ static PyObject* GetMutableMappingBase(void) {
495
+ PyObject* collections = NULL;
496
+ PyObject* mapping = NULL;
497
+ PyObject* bases = NULL;
498
+ if ((collections = PyImport_ImportModule("collections.abc")) &&
499
+ (mapping = PyObject_GetAttrString(collections, "MutableMapping"))) {
500
+ bases = Py_BuildValue("(O)", mapping);
501
+ }
502
+ Py_XDECREF(collections);
503
+ Py_XDECREF(mapping);
504
+ return bases;
505
+ }
506
+
507
+ bool PyUpb_Map_Init(PyObject* m) {
508
+ PyUpb_ModuleState* state = PyUpb_ModuleState_GetFromModule(m);
509
+ PyObject* bases = GetMutableMappingBase();
510
+ if (!bases) return false;
511
+
512
+ state->message_map_container_type =
513
+ PyUpb_AddClassWithBases(m, &PyUpb_MessageMapContainer_Spec, bases);
514
+ state->scalar_map_container_type =
515
+ PyUpb_AddClassWithBases(m, &PyUpb_ScalarMapContainer_Spec, bases);
516
+ state->map_iterator_type = PyUpb_AddClass(m, &PyUpb_MapIterator_Spec);
517
+
518
+ Py_DECREF(bases);
519
+
520
+ return state->message_map_container_type &&
521
+ state->scalar_map_container_type && state->map_iterator_type;
522
+ }
@@ -0,0 +1,66 @@
1
+ /*
2
+ * Copyright (c) 2009-2021, Google LLC
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions are met:
7
+ * * Redistributions of source code must retain the above copyright
8
+ * notice, this list of conditions and the following disclaimer.
9
+ * * Redistributions in binary form must reproduce the above copyright
10
+ * notice, this list of conditions and the following disclaimer in the
11
+ * documentation and/or other materials provided with the distribution.
12
+ * * Neither the name of Google LLC nor the
13
+ * names of its contributors may be used to endorse or promote products
14
+ * derived from this software without specific prior written permission.
15
+ *
16
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
20
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ */
27
+
28
+ #ifndef PYUPB_MAP_H__
29
+ #define PYUPB_MAP_H__
30
+
31
+ #include <stdbool.h>
32
+
33
+ #include "python/python_api.h"
34
+ #include "upb/def.h"
35
+
36
+ // Creates a new repeated field stub for field `f` of message object `parent`.
37
+ // Precondition: `parent` must be a stub.
38
+ PyObject* PyUpb_MapContainer_NewStub(PyObject* parent, const upb_FieldDef* f,
39
+ PyObject* arena);
40
+
41
+ // Returns a map object wrapping `map`, of field type `f`, which must be on
42
+ // `arena`. If an existing wrapper object exists, it will be returned,
43
+ // otherwise a new object will be created. The caller always owns a ref on the
44
+ // returned value.
45
+ PyObject* PyUpb_MapContainer_GetOrCreateWrapper(upb_Map* map,
46
+ const upb_FieldDef* f,
47
+ PyObject* arena);
48
+
49
+ // Reifies a map stub to point to the concrete data in `map`.
50
+ // If `map` is NULL, an appropriate empty map will be constructed.
51
+ void PyUpb_MapContainer_Reify(PyObject* self, upb_Map* map);
52
+
53
+ // Reifies this map object if it is not already reified.
54
+ upb_Map* PyUpb_MapContainer_EnsureReified(PyObject* self);
55
+
56
+ // Assigns `self[key] = val` for the map `self`.
57
+ int PyUpb_MapContainer_AssignSubscript(PyObject* self, PyObject* key,
58
+ PyObject* val);
59
+
60
+ // Invalidates any existing iterators for the map `obj`.
61
+ void PyUpb_MapContainer_Invalidate(PyObject* obj);
62
+
63
+ // Module-level init.
64
+ bool PyUpb_Map_Init(PyObject* m);
65
+
66
+ #endif // PYUPB_MAP_H__