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,836 @@
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
+ /*
29
+ ** Our memory representation for parsing tables and messages themselves.
30
+ ** Functions in this file are used by generated code and possibly reflection.
31
+ **
32
+ ** The definitions in this file are internal to upb.
33
+ **/
34
+
35
+ #ifndef UPB_MSG_INT_H_
36
+ #define UPB_MSG_INT_H_
37
+
38
+ #include <stdint.h>
39
+ #include <stdlib.h>
40
+ #include <string.h>
41
+
42
+ #include "upb/msg.h"
43
+ #include "upb/table_internal.h"
44
+ #include "upb/upb.h"
45
+
46
+ /* Must be last. */
47
+ #include "upb/port_def.inc"
48
+
49
+ #ifdef __cplusplus
50
+ extern "C" {
51
+ #endif
52
+
53
+ /** upb_*Int* conversion routines ********************************************/
54
+
55
+ UPB_INLINE int32_t _upb_Int32_FromI(int v) { return (int32_t)v; }
56
+
57
+ UPB_INLINE int64_t _upb_Int64_FromLL(long long v) { return (int64_t)v; }
58
+
59
+ UPB_INLINE uint32_t _upb_UInt32_FromU(unsigned v) { return (uint32_t)v; }
60
+
61
+ UPB_INLINE uint64_t _upb_UInt64_FromULL(unsigned long long v) {
62
+ return (uint64_t)v;
63
+ }
64
+
65
+ /** upb_MiniTable *************************************************************/
66
+
67
+ /* upb_MiniTable represents the memory layout of a given upb_MessageDef. The
68
+ * members are public so generated code can initialize them, but users MUST NOT
69
+ * read or write any of its members. */
70
+
71
+ typedef struct {
72
+ uint32_t number;
73
+ uint16_t offset;
74
+ int16_t presence; // If >0, hasbit_index. If <0, ~oneof_index
75
+ uint16_t submsg_index; // kUpb_NoSub if descriptortype != MESSAGE/GROUP/ENUM
76
+ uint8_t descriptortype;
77
+ uint8_t mode; /* upb_FieldMode | upb_LabelFlags |
78
+ (upb_FieldRep << kUpb_FieldRep_Shift) */
79
+ } upb_MiniTable_Field;
80
+
81
+ #define kUpb_NoSub ((uint16_t)-1)
82
+
83
+ typedef enum {
84
+ kUpb_FieldMode_Map = 0,
85
+ kUpb_FieldMode_Array = 1,
86
+ kUpb_FieldMode_Scalar = 2,
87
+ } upb_FieldMode;
88
+
89
+ // Mask to isolate the upb_FieldMode from field.mode.
90
+ #define kUpb_FieldMode_Mask 3
91
+
92
+ /* Extra flags on the mode field. */
93
+ typedef enum {
94
+ kUpb_LabelFlags_IsPacked = 4,
95
+ kUpb_LabelFlags_IsExtension = 8,
96
+ } upb_LabelFlags;
97
+
98
+ // Note: we sort by this number when calculating layout order.
99
+ typedef enum {
100
+ kUpb_FieldRep_1Byte = 0,
101
+ kUpb_FieldRep_4Byte = 1,
102
+ kUpb_FieldRep_StringView = 2,
103
+ kUpb_FieldRep_Pointer = 3,
104
+ kUpb_FieldRep_8Byte = 4,
105
+
106
+ kUpb_FieldRep_Shift = 5, // Bit offset of the rep in upb_MiniTable_Field.mode
107
+ kUpb_FieldRep_Max = kUpb_FieldRep_8Byte,
108
+ } upb_FieldRep;
109
+
110
+ UPB_INLINE upb_FieldMode upb_FieldMode_Get(const upb_MiniTable_Field* field) {
111
+ return (upb_FieldMode)(field->mode & 3);
112
+ }
113
+
114
+ UPB_INLINE bool upb_IsRepeatedOrMap(const upb_MiniTable_Field* field) {
115
+ /* This works because upb_FieldMode has no value 3. */
116
+ return !(field->mode & kUpb_FieldMode_Scalar);
117
+ }
118
+
119
+ UPB_INLINE bool upb_IsSubMessage(const upb_MiniTable_Field* field) {
120
+ return field->descriptortype == kUpb_FieldType_Message ||
121
+ field->descriptortype == kUpb_FieldType_Group;
122
+ }
123
+
124
+ struct upb_Decoder;
125
+ struct upb_MiniTable;
126
+
127
+ typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr,
128
+ upb_Message* msg, intptr_t table,
129
+ uint64_t hasbits, uint64_t data);
130
+
131
+ typedef struct {
132
+ uint64_t field_data;
133
+ _upb_FieldParser* field_parser;
134
+ } _upb_FastTable_Entry;
135
+
136
+ typedef struct {
137
+ const int32_t* values; // List of values <0 or >63
138
+ uint64_t mask; // Bits are set for acceptable value 0 <= x < 64
139
+ int value_count;
140
+ } upb_MiniTable_Enum;
141
+
142
+ typedef union {
143
+ const struct upb_MiniTable* submsg;
144
+ const upb_MiniTable_Enum* subenum;
145
+ } upb_MiniTable_Sub;
146
+
147
+ typedef enum {
148
+ kUpb_ExtMode_NonExtendable = 0, // Non-extendable message.
149
+ kUpb_ExtMode_Extendable = 1, // Normal extendable message.
150
+ kUpb_ExtMode_IsMessageSet = 2, // MessageSet message.
151
+ kUpb_ExtMode_IsMessageSet_ITEM =
152
+ 3, // MessageSet item (temporary only, see decode.c)
153
+
154
+ // During table building we steal a bit to indicate that the message is a map
155
+ // entry. *Only* used during table building!
156
+ kUpb_ExtMode_IsMapEntry = 4,
157
+ } upb_ExtMode;
158
+
159
+ /* MessageSet wire format is:
160
+ * message MessageSet {
161
+ * repeated group Item = 1 {
162
+ * required int32 type_id = 2;
163
+ * required bytes message = 3;
164
+ * }
165
+ * }
166
+ */
167
+ typedef enum {
168
+ _UPB_MSGSET_ITEM = 1,
169
+ _UPB_MSGSET_TYPEID = 2,
170
+ _UPB_MSGSET_MESSAGE = 3,
171
+ } upb_msgext_fieldnum;
172
+
173
+ struct upb_MiniTable {
174
+ const upb_MiniTable_Sub* subs;
175
+ const upb_MiniTable_Field* fields;
176
+ /* Must be aligned to sizeof(void*). Doesn't include internal members like
177
+ * unknown fields, extension dict, pointer to msglayout, etc. */
178
+ uint16_t size;
179
+ uint16_t field_count;
180
+ uint8_t ext; // upb_ExtMode, declared as uint8_t so sizeof(ext) == 1
181
+ uint8_t dense_below;
182
+ uint8_t table_mask;
183
+ uint8_t required_count; // Required fields have the lowest hasbits.
184
+ /* To statically initialize the tables of variable length, we need a flexible
185
+ * array member, and we need to compile in gnu99 mode (constant initialization
186
+ * of flexible array members is a GNU extension, not in C99 unfortunately. */
187
+ _upb_FastTable_Entry fasttable[];
188
+ };
189
+
190
+ typedef struct {
191
+ upb_MiniTable_Field field;
192
+ const upb_MiniTable* extendee;
193
+ upb_MiniTable_Sub sub; /* NULL unless submessage or proto2 enum */
194
+ } upb_MiniTable_Extension;
195
+
196
+ typedef struct {
197
+ const upb_MiniTable** msgs;
198
+ const upb_MiniTable_Enum** enums;
199
+ const upb_MiniTable_Extension** exts;
200
+ int msg_count;
201
+ int enum_count;
202
+ int ext_count;
203
+ } upb_MiniTable_File;
204
+
205
+ // Computes a bitmask in which the |l->required_count| lowest bits are set,
206
+ // except that we skip the lowest bit (because upb never uses hasbit 0).
207
+ //
208
+ // Sample output:
209
+ // requiredmask(1) => 0b10 (0x2)
210
+ // requiredmask(5) => 0b111110 (0x3e)
211
+ UPB_INLINE uint64_t upb_MiniTable_requiredmask(const upb_MiniTable* l) {
212
+ int n = l->required_count;
213
+ assert(0 < n && n <= 63);
214
+ return ((1ULL << n) - 1) << 1;
215
+ }
216
+
217
+ /** upb_ExtensionRegistry *****************************************************/
218
+
219
+ /* Adds the given extension info for message type |l| and field number |num|
220
+ * into the registry. Returns false if this message type and field number were
221
+ * already in the map, or if memory allocation fails. */
222
+ bool _upb_extreg_add(upb_ExtensionRegistry* r,
223
+ const upb_MiniTable_Extension** e, size_t count);
224
+
225
+ /* Looks up the extension (if any) defined for message type |l| and field
226
+ * number |num|. If an extension was found, copies the field info into |*ext|
227
+ * and returns true. Otherwise returns false. */
228
+ const upb_MiniTable_Extension* _upb_extreg_get(const upb_ExtensionRegistry* r,
229
+ const upb_MiniTable* l,
230
+ uint32_t num);
231
+
232
+ /** upb_Message ***************************************************************/
233
+
234
+ /* Internal members of a upb_Message that track unknown fields and/or
235
+ * extensions. We can change this without breaking binary compatibility. We put
236
+ * these before the user's data. The user's upb_Message* points after the
237
+ * upb_Message_Internal. */
238
+
239
+ typedef struct {
240
+ /* Total size of this structure, including the data that follows.
241
+ * Must be aligned to 8, which is alignof(upb_Message_Extension) */
242
+ uint32_t size;
243
+
244
+ /* Offsets relative to the beginning of this structure.
245
+ *
246
+ * Unknown data grows forward from the beginning to unknown_end.
247
+ * Extension data grows backward from size to ext_begin.
248
+ * When the two meet, we're out of data and have to realloc.
249
+ *
250
+ * If we imagine that the final member of this struct is:
251
+ * char data[size - overhead]; // overhead =
252
+ * sizeof(upb_Message_InternalData)
253
+ *
254
+ * Then we have:
255
+ * unknown data: data[0 .. (unknown_end - overhead)]
256
+ * extensions data: data[(ext_begin - overhead) .. (size - overhead)] */
257
+ uint32_t unknown_end;
258
+ uint32_t ext_begin;
259
+ /* Data follows, as if there were an array:
260
+ * char data[size - sizeof(upb_Message_InternalData)]; */
261
+ } upb_Message_InternalData;
262
+
263
+ typedef struct {
264
+ upb_Message_InternalData* internal;
265
+ /* Message data follows. */
266
+ } upb_Message_Internal;
267
+
268
+ /* Maps upb_CType -> memory size. */
269
+ extern char _upb_CTypeo_size[12];
270
+
271
+ UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* l) {
272
+ return l->size + sizeof(upb_Message_Internal);
273
+ }
274
+
275
+ UPB_INLINE upb_Message* _upb_Message_New_inl(const upb_MiniTable* l,
276
+ upb_Arena* a) {
277
+ size_t size = upb_msg_sizeof(l);
278
+ void* mem = upb_Arena_Malloc(a, size);
279
+ upb_Message* msg;
280
+ if (UPB_UNLIKELY(!mem)) return NULL;
281
+ msg = UPB_PTR_AT(mem, sizeof(upb_Message_Internal), upb_Message);
282
+ memset(mem, 0, size);
283
+ return msg;
284
+ }
285
+
286
+ /* Creates a new messages with the given layout on the given arena. */
287
+ upb_Message* _upb_Message_New(const upb_MiniTable* l, upb_Arena* a);
288
+
289
+ UPB_INLINE upb_Message_Internal* upb_Message_Getinternal(upb_Message* msg) {
290
+ ptrdiff_t size = sizeof(upb_Message_Internal);
291
+ return (upb_Message_Internal*)((char*)msg - size);
292
+ }
293
+
294
+ /* Clears the given message. */
295
+ void _upb_Message_Clear(upb_Message* msg, const upb_MiniTable* l);
296
+
297
+ /* Discards the unknown fields for this message only. */
298
+ void _upb_Message_DiscardUnknown_shallow(upb_Message* msg);
299
+
300
+ /* Adds unknown data (serialized protobuf data) to the given message. The data
301
+ * is copied into the message instance. */
302
+ bool _upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len,
303
+ upb_Arena* arena);
304
+
305
+ /** upb_Message_Extension *****************************************************/
306
+
307
+ /* The internal representation of an extension is self-describing: it contains
308
+ * enough information that we can serialize it to binary format without needing
309
+ * to look it up in a upb_ExtensionRegistry.
310
+ *
311
+ * This representation allocates 16 bytes to data on 64-bit platforms. This is
312
+ * rather wasteful for scalars (in the extreme case of bool, it wastes 15
313
+ * bytes). We accept this because we expect messages to be the most common
314
+ * extension type. */
315
+ typedef struct {
316
+ const upb_MiniTable_Extension* ext;
317
+ union {
318
+ upb_StringView str;
319
+ void* ptr;
320
+ char scalar_data[8];
321
+ } data;
322
+ } upb_Message_Extension;
323
+
324
+ /* Adds the given extension data to the given message. |ext| is copied into the
325
+ * message instance. This logically replaces any previously-added extension with
326
+ * this number */
327
+ upb_Message_Extension* _upb_Message_GetOrCreateExtension(
328
+ upb_Message* msg, const upb_MiniTable_Extension* ext, upb_Arena* arena);
329
+
330
+ /* Returns an array of extensions for this message. Note: the array is
331
+ * ordered in reverse relative to the order of creation. */
332
+ const upb_Message_Extension* _upb_Message_Getexts(const upb_Message* msg,
333
+ size_t* count);
334
+
335
+ /* Returns an extension for the given field number, or NULL if no extension
336
+ * exists for this field number. */
337
+ const upb_Message_Extension* _upb_Message_Getext(
338
+ const upb_Message* msg, const upb_MiniTable_Extension* ext);
339
+
340
+ void _upb_Message_Clearext(upb_Message* msg,
341
+ const upb_MiniTable_Extension* ext);
342
+
343
+ void _upb_Message_Clearext(upb_Message* msg,
344
+ const upb_MiniTable_Extension* ext);
345
+
346
+ /** Hasbit access *************************************************************/
347
+
348
+ UPB_INLINE bool _upb_hasbit(const upb_Message* msg, size_t idx) {
349
+ return (*UPB_PTR_AT(msg, idx / 8, const char) & (1 << (idx % 8))) != 0;
350
+ }
351
+
352
+ UPB_INLINE void _upb_sethas(const upb_Message* msg, size_t idx) {
353
+ (*UPB_PTR_AT(msg, idx / 8, char)) |= (char)(1 << (idx % 8));
354
+ }
355
+
356
+ UPB_INLINE void _upb_clearhas(const upb_Message* msg, size_t idx) {
357
+ (*UPB_PTR_AT(msg, idx / 8, char)) &= (char)(~(1 << (idx % 8)));
358
+ }
359
+
360
+ UPB_INLINE size_t _upb_Message_Hasidx(const upb_MiniTable_Field* f) {
361
+ UPB_ASSERT(f->presence > 0);
362
+ return f->presence;
363
+ }
364
+
365
+ UPB_INLINE bool _upb_hasbit_field(const upb_Message* msg,
366
+ const upb_MiniTable_Field* f) {
367
+ return _upb_hasbit(msg, _upb_Message_Hasidx(f));
368
+ }
369
+
370
+ UPB_INLINE void _upb_sethas_field(const upb_Message* msg,
371
+ const upb_MiniTable_Field* f) {
372
+ _upb_sethas(msg, _upb_Message_Hasidx(f));
373
+ }
374
+
375
+ UPB_INLINE void _upb_clearhas_field(const upb_Message* msg,
376
+ const upb_MiniTable_Field* f) {
377
+ _upb_clearhas(msg, _upb_Message_Hasidx(f));
378
+ }
379
+
380
+ /** Oneof case access *********************************************************/
381
+
382
+ UPB_INLINE uint32_t* _upb_oneofcase(upb_Message* msg, size_t case_ofs) {
383
+ return UPB_PTR_AT(msg, case_ofs, uint32_t);
384
+ }
385
+
386
+ UPB_INLINE uint32_t _upb_getoneofcase(const void* msg, size_t case_ofs) {
387
+ return *UPB_PTR_AT(msg, case_ofs, uint32_t);
388
+ }
389
+
390
+ UPB_INLINE size_t _upb_oneofcase_ofs(const upb_MiniTable_Field* f) {
391
+ UPB_ASSERT(f->presence < 0);
392
+ return ~(ptrdiff_t)f->presence;
393
+ }
394
+
395
+ UPB_INLINE uint32_t* _upb_oneofcase_field(upb_Message* msg,
396
+ const upb_MiniTable_Field* f) {
397
+ return _upb_oneofcase(msg, _upb_oneofcase_ofs(f));
398
+ }
399
+
400
+ UPB_INLINE uint32_t _upb_getoneofcase_field(const upb_Message* msg,
401
+ const upb_MiniTable_Field* f) {
402
+ return _upb_getoneofcase(msg, _upb_oneofcase_ofs(f));
403
+ }
404
+
405
+ UPB_INLINE bool _upb_has_submsg_nohasbit(const upb_Message* msg, size_t ofs) {
406
+ return *UPB_PTR_AT(msg, ofs, const upb_Message*) != NULL;
407
+ }
408
+
409
+ /** upb_Array *****************************************************************/
410
+
411
+ /* Our internal representation for repeated fields. */
412
+ typedef struct {
413
+ uintptr_t data; /* Tagged ptr: low 3 bits of ptr are lg2(elem size). */
414
+ size_t len; /* Measured in elements. */
415
+ size_t size; /* Measured in elements. */
416
+ uint64_t junk;
417
+ } upb_Array;
418
+
419
+ UPB_INLINE const void* _upb_array_constptr(const upb_Array* arr) {
420
+ UPB_ASSERT((arr->data & 7) <= 4);
421
+ return (void*)(arr->data & ~(uintptr_t)7);
422
+ }
423
+
424
+ UPB_INLINE uintptr_t _upb_array_tagptr(void* ptr, int elem_size_lg2) {
425
+ UPB_ASSERT(elem_size_lg2 <= 4);
426
+ return (uintptr_t)ptr | elem_size_lg2;
427
+ }
428
+
429
+ UPB_INLINE void* _upb_array_ptr(upb_Array* arr) {
430
+ return (void*)_upb_array_constptr(arr);
431
+ }
432
+
433
+ UPB_INLINE uintptr_t _upb_tag_arrptr(void* ptr, int elem_size_lg2) {
434
+ UPB_ASSERT(elem_size_lg2 <= 4);
435
+ UPB_ASSERT(((uintptr_t)ptr & 7) == 0);
436
+ return (uintptr_t)ptr | (unsigned)elem_size_lg2;
437
+ }
438
+
439
+ UPB_INLINE upb_Array* _upb_Array_New(upb_Arena* a, size_t init_size,
440
+ int elem_size_lg2) {
441
+ const size_t arr_size = UPB_ALIGN_UP(sizeof(upb_Array), 8);
442
+ const size_t bytes = sizeof(upb_Array) + (init_size << elem_size_lg2);
443
+ upb_Array* arr = (upb_Array*)upb_Arena_Malloc(a, bytes);
444
+ if (!arr) return NULL;
445
+ arr->data = _upb_tag_arrptr(UPB_PTR_AT(arr, arr_size, void), elem_size_lg2);
446
+ arr->len = 0;
447
+ arr->size = init_size;
448
+ return arr;
449
+ }
450
+
451
+ /* Resizes the capacity of the array to be at least min_size. */
452
+ bool _upb_array_realloc(upb_Array* arr, size_t min_size, upb_Arena* arena);
453
+
454
+ /* Fallback functions for when the accessors require a resize. */
455
+ void* _upb_Array_Resize_fallback(upb_Array** arr_ptr, size_t size,
456
+ int elem_size_lg2, upb_Arena* arena);
457
+ bool _upb_Array_Append_fallback(upb_Array** arr_ptr, const void* value,
458
+ int elem_size_lg2, upb_Arena* arena);
459
+
460
+ UPB_INLINE bool _upb_array_reserve(upb_Array* arr, size_t size,
461
+ upb_Arena* arena) {
462
+ if (arr->size < size) return _upb_array_realloc(arr, size, arena);
463
+ return true;
464
+ }
465
+
466
+ UPB_INLINE bool _upb_Array_Resize(upb_Array* arr, size_t size,
467
+ upb_Arena* arena) {
468
+ if (!_upb_array_reserve(arr, size, arena)) return false;
469
+ arr->len = size;
470
+ return true;
471
+ }
472
+
473
+ UPB_INLINE void _upb_array_detach(const void* msg, size_t ofs) {
474
+ *UPB_PTR_AT(msg, ofs, upb_Array*) = NULL;
475
+ }
476
+
477
+ UPB_INLINE const void* _upb_array_accessor(const void* msg, size_t ofs,
478
+ size_t* size) {
479
+ const upb_Array* arr = *UPB_PTR_AT(msg, ofs, const upb_Array*);
480
+ if (arr) {
481
+ if (size) *size = arr->len;
482
+ return _upb_array_constptr(arr);
483
+ } else {
484
+ if (size) *size = 0;
485
+ return NULL;
486
+ }
487
+ }
488
+
489
+ UPB_INLINE void* _upb_array_mutable_accessor(void* msg, size_t ofs,
490
+ size_t* size) {
491
+ upb_Array* arr = *UPB_PTR_AT(msg, ofs, upb_Array*);
492
+ if (arr) {
493
+ if (size) *size = arr->len;
494
+ return _upb_array_ptr(arr);
495
+ } else {
496
+ if (size) *size = 0;
497
+ return NULL;
498
+ }
499
+ }
500
+
501
+ UPB_INLINE void* _upb_Array_Resize_accessor2(void* msg, size_t ofs, size_t size,
502
+ int elem_size_lg2,
503
+ upb_Arena* arena) {
504
+ upb_Array** arr_ptr = UPB_PTR_AT(msg, ofs, upb_Array*);
505
+ upb_Array* arr = *arr_ptr;
506
+ if (!arr || arr->size < size) {
507
+ return _upb_Array_Resize_fallback(arr_ptr, size, elem_size_lg2, arena);
508
+ }
509
+ arr->len = size;
510
+ return _upb_array_ptr(arr);
511
+ }
512
+
513
+ UPB_INLINE bool _upb_Array_Append_accessor2(void* msg, size_t ofs,
514
+ int elem_size_lg2,
515
+ const void* value,
516
+ upb_Arena* arena) {
517
+ upb_Array** arr_ptr = UPB_PTR_AT(msg, ofs, upb_Array*);
518
+ size_t elem_size = 1 << elem_size_lg2;
519
+ upb_Array* arr = *arr_ptr;
520
+ void* ptr;
521
+ if (!arr || arr->len == arr->size) {
522
+ return _upb_Array_Append_fallback(arr_ptr, value, elem_size_lg2, arena);
523
+ }
524
+ ptr = _upb_array_ptr(arr);
525
+ memcpy(UPB_PTR_AT(ptr, arr->len * elem_size, char), value, elem_size);
526
+ arr->len++;
527
+ return true;
528
+ }
529
+
530
+ /* Used by old generated code, remove once all code has been regenerated. */
531
+ UPB_INLINE int _upb_sizelg2(upb_CType type) {
532
+ switch (type) {
533
+ case kUpb_CType_Bool:
534
+ return 0;
535
+ case kUpb_CType_Float:
536
+ case kUpb_CType_Int32:
537
+ case kUpb_CType_UInt32:
538
+ case kUpb_CType_Enum:
539
+ return 2;
540
+ case kUpb_CType_Message:
541
+ return UPB_SIZE(2, 3);
542
+ case kUpb_CType_Double:
543
+ case kUpb_CType_Int64:
544
+ case kUpb_CType_UInt64:
545
+ return 3;
546
+ case kUpb_CType_String:
547
+ case kUpb_CType_Bytes:
548
+ return UPB_SIZE(3, 4);
549
+ }
550
+ UPB_UNREACHABLE();
551
+ }
552
+ UPB_INLINE void* _upb_Array_Resize_accessor(void* msg, size_t ofs, size_t size,
553
+ upb_CType type, upb_Arena* arena) {
554
+ return _upb_Array_Resize_accessor2(msg, ofs, size, _upb_sizelg2(type), arena);
555
+ }
556
+ UPB_INLINE bool _upb_Array_Append_accessor(void* msg, size_t ofs,
557
+ size_t elem_size, upb_CType type,
558
+ const void* value,
559
+ upb_Arena* arena) {
560
+ (void)elem_size;
561
+ return _upb_Array_Append_accessor2(msg, ofs, _upb_sizelg2(type), value,
562
+ arena);
563
+ }
564
+
565
+ /** upb_Map *******************************************************************/
566
+
567
+ /* Right now we use strmaps for everything. We'll likely want to use
568
+ * integer-specific maps for integer-keyed maps.*/
569
+ typedef struct {
570
+ /* Size of key and val, based on the map type. Strings are represented as '0'
571
+ * because they must be handled specially. */
572
+ char key_size;
573
+ char val_size;
574
+
575
+ upb_strtable table;
576
+ } upb_Map;
577
+
578
+ /* Map entries aren't actually stored, they are only used during parsing. For
579
+ * parsing, it helps a lot if all map entry messages have the same layout.
580
+ * The compiler and def.c must ensure that all map entries have this layout. */
581
+ typedef struct {
582
+ upb_Message_Internal internal;
583
+ union {
584
+ upb_StringView str; /* For str/bytes. */
585
+ upb_value val; /* For all other types. */
586
+ } k;
587
+ union {
588
+ upb_StringView str; /* For str/bytes. */
589
+ upb_value val; /* For all other types. */
590
+ } v;
591
+ } upb_MapEntry;
592
+
593
+ /* Creates a new map on the given arena with this key/value type. */
594
+ upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size);
595
+
596
+ /* Converting between internal table representation and user values.
597
+ *
598
+ * _upb_map_tokey() and _upb_map_fromkey() are inverses.
599
+ * _upb_map_tovalue() and _upb_map_fromvalue() are inverses.
600
+ *
601
+ * These functions account for the fact that strings are treated differently
602
+ * from other types when stored in a map.
603
+ */
604
+
605
+ UPB_INLINE upb_StringView _upb_map_tokey(const void* key, size_t size) {
606
+ if (size == UPB_MAPTYPE_STRING) {
607
+ return *(upb_StringView*)key;
608
+ } else {
609
+ return upb_StringView_FromDataAndSize((const char*)key, size);
610
+ }
611
+ }
612
+
613
+ UPB_INLINE void _upb_map_fromkey(upb_StringView key, void* out, size_t size) {
614
+ if (size == UPB_MAPTYPE_STRING) {
615
+ memcpy(out, &key, sizeof(key));
616
+ } else {
617
+ memcpy(out, key.data, size);
618
+ }
619
+ }
620
+
621
+ UPB_INLINE bool _upb_map_tovalue(const void* val, size_t size,
622
+ upb_value* msgval, upb_Arena* a) {
623
+ if (size == UPB_MAPTYPE_STRING) {
624
+ upb_StringView* strp = (upb_StringView*)upb_Arena_Malloc(a, sizeof(*strp));
625
+ if (!strp) return false;
626
+ *strp = *(upb_StringView*)val;
627
+ *msgval = upb_value_ptr(strp);
628
+ } else {
629
+ memcpy(msgval, val, size);
630
+ }
631
+ return true;
632
+ }
633
+
634
+ UPB_INLINE void _upb_map_fromvalue(upb_value val, void* out, size_t size) {
635
+ if (size == UPB_MAPTYPE_STRING) {
636
+ const upb_StringView* strp = (const upb_StringView*)upb_value_getptr(val);
637
+ memcpy(out, strp, sizeof(upb_StringView));
638
+ } else {
639
+ memcpy(out, &val, size);
640
+ }
641
+ }
642
+
643
+ /* Map operations, shared by reflection and generated code. */
644
+
645
+ UPB_INLINE size_t _upb_Map_Size(const upb_Map* map) {
646
+ return map->table.t.count;
647
+ }
648
+
649
+ UPB_INLINE bool _upb_Map_Get(const upb_Map* map, const void* key,
650
+ size_t key_size, void* val, size_t val_size) {
651
+ upb_value tabval;
652
+ upb_StringView k = _upb_map_tokey(key, key_size);
653
+ bool ret = upb_strtable_lookup2(&map->table, k.data, k.size, &tabval);
654
+ if (ret && val) {
655
+ _upb_map_fromvalue(tabval, val, val_size);
656
+ }
657
+ return ret;
658
+ }
659
+
660
+ UPB_INLINE void* _upb_map_next(const upb_Map* map, size_t* iter) {
661
+ upb_strtable_iter it;
662
+ it.t = &map->table;
663
+ it.index = *iter;
664
+ upb_strtable_next(&it);
665
+ *iter = it.index;
666
+ if (upb_strtable_done(&it)) return NULL;
667
+ return (void*)str_tabent(&it);
668
+ }
669
+
670
+ typedef enum {
671
+ // LINT.IfChange
672
+ _kUpb_MapInsertStatus_Inserted = 0,
673
+ _kUpb_MapInsertStatus_Replaced = 1,
674
+ _kUpb_MapInsertStatus_OutOfMemory = 2,
675
+ // LINT.ThenChange(//depot/google3/third_party/upb/upb/collections.h)
676
+ } _upb_MapInsertStatus;
677
+
678
+ UPB_INLINE _upb_MapInsertStatus _upb_Map_Insert(upb_Map* map, const void* key,
679
+ size_t key_size, void* val,
680
+ size_t val_size, upb_Arena* a) {
681
+ upb_StringView strkey = _upb_map_tokey(key, key_size);
682
+ upb_value tabval = {0};
683
+ if (!_upb_map_tovalue(val, val_size, &tabval, a)) {
684
+ return _kUpb_MapInsertStatus_OutOfMemory;
685
+ }
686
+
687
+ /* TODO(haberman): add overwrite operation to minimize number of lookups. */
688
+ bool removed =
689
+ upb_strtable_remove2(&map->table, strkey.data, strkey.size, NULL);
690
+ if (!upb_strtable_insert(&map->table, strkey.data, strkey.size, tabval, a)) {
691
+ return _kUpb_MapInsertStatus_OutOfMemory;
692
+ }
693
+ return removed ? _kUpb_MapInsertStatus_Replaced
694
+ : _kUpb_MapInsertStatus_Inserted;
695
+ }
696
+
697
+ UPB_INLINE bool _upb_Map_Delete(upb_Map* map, const void* key,
698
+ size_t key_size) {
699
+ upb_StringView k = _upb_map_tokey(key, key_size);
700
+ return upb_strtable_remove2(&map->table, k.data, k.size, NULL);
701
+ }
702
+
703
+ UPB_INLINE void _upb_Map_Clear(upb_Map* map) {
704
+ upb_strtable_clear(&map->table);
705
+ }
706
+
707
+ /* Message map operations, these get the map from the message first. */
708
+
709
+ UPB_INLINE size_t _upb_msg_map_size(const upb_Message* msg, size_t ofs) {
710
+ upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*);
711
+ return map ? _upb_Map_Size(map) : 0;
712
+ }
713
+
714
+ UPB_INLINE bool _upb_msg_map_get(const upb_Message* msg, size_t ofs,
715
+ const void* key, size_t key_size, void* val,
716
+ size_t val_size) {
717
+ upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*);
718
+ if (!map) return false;
719
+ return _upb_Map_Get(map, key, key_size, val, val_size);
720
+ }
721
+
722
+ UPB_INLINE void* _upb_msg_map_next(const upb_Message* msg, size_t ofs,
723
+ size_t* iter) {
724
+ upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*);
725
+ if (!map) return NULL;
726
+ return _upb_map_next(map, iter);
727
+ }
728
+
729
+ UPB_INLINE bool _upb_msg_map_set(upb_Message* msg, size_t ofs, const void* key,
730
+ size_t key_size, void* val, size_t val_size,
731
+ upb_Arena* arena) {
732
+ upb_Map** map = UPB_PTR_AT(msg, ofs, upb_Map*);
733
+ if (!*map) {
734
+ *map = _upb_Map_New(arena, key_size, val_size);
735
+ }
736
+ return _upb_Map_Insert(*map, key, key_size, val, val_size, arena) !=
737
+ _kUpb_MapInsertStatus_OutOfMemory;
738
+ }
739
+
740
+ UPB_INLINE bool _upb_msg_map_delete(upb_Message* msg, size_t ofs,
741
+ const void* key, size_t key_size) {
742
+ upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*);
743
+ if (!map) return false;
744
+ return _upb_Map_Delete(map, key, key_size);
745
+ }
746
+
747
+ UPB_INLINE void _upb_msg_map_clear(upb_Message* msg, size_t ofs) {
748
+ upb_Map* map = *UPB_PTR_AT(msg, ofs, upb_Map*);
749
+ if (!map) return;
750
+ _upb_Map_Clear(map);
751
+ }
752
+
753
+ /* Accessing map key/value from a pointer, used by generated code only. */
754
+
755
+ UPB_INLINE void _upb_msg_map_key(const void* msg, void* key, size_t size) {
756
+ const upb_tabent* ent = (const upb_tabent*)msg;
757
+ uint32_t u32len;
758
+ upb_StringView k;
759
+ k.data = upb_tabstr(ent->key, &u32len);
760
+ k.size = u32len;
761
+ _upb_map_fromkey(k, key, size);
762
+ }
763
+
764
+ UPB_INLINE void _upb_msg_map_value(const void* msg, void* val, size_t size) {
765
+ const upb_tabent* ent = (const upb_tabent*)msg;
766
+ upb_value v = {ent->val.val};
767
+ _upb_map_fromvalue(v, val, size);
768
+ }
769
+
770
+ UPB_INLINE void _upb_msg_map_set_value(void* msg, const void* val,
771
+ size_t size) {
772
+ upb_tabent* ent = (upb_tabent*)msg;
773
+ /* This is like _upb_map_tovalue() except the entry already exists so we can
774
+ * reuse the allocated upb_StringView for string fields. */
775
+ if (size == UPB_MAPTYPE_STRING) {
776
+ upb_StringView* strp = (upb_StringView*)(uintptr_t)ent->val.val;
777
+ memcpy(strp, val, sizeof(*strp));
778
+ } else {
779
+ memcpy(&ent->val.val, val, size);
780
+ }
781
+ }
782
+
783
+ /** _upb_mapsorter ************************************************************/
784
+
785
+ /* _upb_mapsorter sorts maps and provides ordered iteration over the entries.
786
+ * Since maps can be recursive (map values can be messages which contain other
787
+ * maps). _upb_mapsorter can contain a stack of maps. */
788
+
789
+ typedef struct {
790
+ upb_tabent const** entries;
791
+ int size;
792
+ int cap;
793
+ } _upb_mapsorter;
794
+
795
+ typedef struct {
796
+ int start;
797
+ int pos;
798
+ int end;
799
+ } _upb_sortedmap;
800
+
801
+ UPB_INLINE void _upb_mapsorter_init(_upb_mapsorter* s) {
802
+ s->entries = NULL;
803
+ s->size = 0;
804
+ s->cap = 0;
805
+ }
806
+
807
+ UPB_INLINE void _upb_mapsorter_destroy(_upb_mapsorter* s) {
808
+ if (s->entries) free(s->entries);
809
+ }
810
+
811
+ bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type,
812
+ const upb_Map* map, _upb_sortedmap* sorted);
813
+
814
+ UPB_INLINE void _upb_mapsorter_popmap(_upb_mapsorter* s,
815
+ _upb_sortedmap* sorted) {
816
+ s->size = sorted->start;
817
+ }
818
+
819
+ UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter* s, const upb_Map* map,
820
+ _upb_sortedmap* sorted, upb_MapEntry* ent) {
821
+ if (sorted->pos == sorted->end) return false;
822
+ const upb_tabent* tabent = s->entries[sorted->pos++];
823
+ upb_StringView key = upb_tabstrview(tabent->key);
824
+ _upb_map_fromkey(key, &ent->k, map->key_size);
825
+ upb_value val = {tabent->val.val};
826
+ _upb_map_fromvalue(val, &ent->v, map->val_size);
827
+ return true;
828
+ }
829
+
830
+ #ifdef __cplusplus
831
+ } /* extern "C" */
832
+ #endif
833
+
834
+ #include "upb/port_undef.inc"
835
+
836
+ #endif /* UPB_MSG_INT_H_ */