ruby_memprofiler_pprof 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,1147 @@
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 "upb/mini_table.h"
29
+
30
+ #include <inttypes.h>
31
+ #include <setjmp.h>
32
+
33
+ #include "upb/msg_internal.h"
34
+ #include "upb/upb.h"
35
+
36
+ // Must be last.
37
+ #include "upb/port_def.inc"
38
+
39
+ typedef enum {
40
+ kUpb_EncodedType_Double = 0,
41
+ kUpb_EncodedType_Float = 1,
42
+ kUpb_EncodedType_Fixed32 = 2,
43
+ kUpb_EncodedType_Fixed64 = 3,
44
+ kUpb_EncodedType_SFixed32 = 4,
45
+ kUpb_EncodedType_SFixed64 = 5,
46
+ kUpb_EncodedType_Int32 = 6,
47
+ kUpb_EncodedType_UInt32 = 7,
48
+ kUpb_EncodedType_SInt32 = 8,
49
+ kUpb_EncodedType_Int64 = 9,
50
+ kUpb_EncodedType_UInt64 = 10,
51
+ kUpb_EncodedType_SInt64 = 11,
52
+ kUpb_EncodedType_Enum = 12,
53
+ kUpb_EncodedType_Bool = 13,
54
+ kUpb_EncodedType_Bytes = 14,
55
+ kUpb_EncodedType_String = 15,
56
+ kUpb_EncodedType_Group = 16,
57
+ kUpb_EncodedType_Message = 17,
58
+
59
+ kUpb_EncodedType_RepeatedBase = 20,
60
+ } upb_EncodedType;
61
+
62
+ typedef enum {
63
+ kUpb_EncodedFieldModifier_FlipPacked = 1 << 0,
64
+ kUpb_EncodedFieldModifier_IsClosedEnum = 1 << 1,
65
+ // upb only.
66
+ kUpb_EncodedFieldModifier_IsProto3Singular = 1 << 2,
67
+ kUpb_EncodedFieldModifier_IsRequired = 1 << 3,
68
+ } upb_EncodedFieldModifier;
69
+
70
+ enum {
71
+ kUpb_EncodedValue_MinField = ' ',
72
+ kUpb_EncodedValue_MaxField = 'K',
73
+ kUpb_EncodedValue_MinModifier = 'L',
74
+ kUpb_EncodedValue_MaxModifier = '[',
75
+ kUpb_EncodedValue_End = '^',
76
+ kUpb_EncodedValue_MinSkip = '_',
77
+ kUpb_EncodedValue_MaxSkip = '~',
78
+ kUpb_EncodedValue_OneofSeparator = '~',
79
+ kUpb_EncodedValue_FieldSeparator = '|',
80
+ kUpb_EncodedValue_MinOneofField = ' ',
81
+ kUpb_EncodedValue_MaxOneofField = 'b',
82
+ kUpb_EncodedValue_MaxEnumMask = 'A',
83
+ };
84
+
85
+ char upb_ToBase92(int8_t ch) {
86
+ static const char kUpb_ToBase92[] = {
87
+ ' ', '!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-', '.', '/',
88
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=',
89
+ '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
90
+ 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
91
+ 'Z', '[', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
92
+ 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
93
+ 'w', 'x', 'y', 'z', '{', '|', '}', '~',
94
+ };
95
+
96
+ UPB_ASSERT(0 <= ch && ch < 92);
97
+ return kUpb_ToBase92[ch];
98
+ }
99
+
100
+ char upb_FromBase92(uint8_t ch) {
101
+ static const int8_t kUpb_FromBase92[] = {
102
+ 0, 1, -1, 2, 3, 4, 5, -1, 6, 7, 8, 9, 10, 11, 12, 13,
103
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
104
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
105
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, -1, 58, 59, 60,
106
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
107
+ 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
108
+ };
109
+
110
+ if (' ' > ch || ch > '~') return -1;
111
+ return kUpb_FromBase92[ch - ' '];
112
+ }
113
+
114
+ bool upb_IsTypePackable(upb_FieldType type) {
115
+ // clang-format off
116
+ static const unsigned kUnpackableTypes =
117
+ (1 << kUpb_FieldType_String) |
118
+ (1 << kUpb_FieldType_Bytes) |
119
+ (1 << kUpb_FieldType_Message) |
120
+ (1 << kUpb_FieldType_Group);
121
+ // clang-format on
122
+ return (1 << type) & ~kUnpackableTypes;
123
+ }
124
+
125
+ /** upb_MtDataEncoder *********************************************************/
126
+
127
+ typedef struct {
128
+ uint64_t present_values_mask;
129
+ uint32_t last_written_value;
130
+ } upb_MtDataEncoderInternal_EnumState;
131
+
132
+ typedef struct {
133
+ uint64_t msg_modifiers;
134
+ uint32_t last_field_num;
135
+ enum {
136
+ kUpb_OneofState_NotStarted,
137
+ kUpb_OneofState_StartedOneof,
138
+ kUpb_OneofState_EmittedOneofField,
139
+ } oneof_state;
140
+ } upb_MtDataEncoderInternal_MsgState;
141
+
142
+ typedef struct {
143
+ char* buf_start; // Only for checking kUpb_MtDataEncoder_MinSize.
144
+ union {
145
+ upb_MtDataEncoderInternal_EnumState enum_state;
146
+ upb_MtDataEncoderInternal_MsgState msg_state;
147
+ } state;
148
+ } upb_MtDataEncoderInternal;
149
+
150
+ static upb_MtDataEncoderInternal* upb_MtDataEncoder_GetInternal(
151
+ upb_MtDataEncoder* e, char* buf_start) {
152
+ UPB_ASSERT(sizeof(upb_MtDataEncoderInternal) <= sizeof(e->internal));
153
+ upb_MtDataEncoderInternal* ret = (upb_MtDataEncoderInternal*)e->internal;
154
+ ret->buf_start = buf_start;
155
+ return ret;
156
+ }
157
+
158
+ static char* upb_MtDataEncoder_Put(upb_MtDataEncoder* e, char* ptr, char ch) {
159
+ upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
160
+ UPB_ASSERT(ptr - in->buf_start < kUpb_MtDataEncoder_MinSize);
161
+ if (ptr == e->end) return NULL;
162
+ *ptr++ = upb_ToBase92(ch);
163
+ return ptr;
164
+ }
165
+
166
+ static char* upb_MtDataEncoder_PutBase92Varint(upb_MtDataEncoder* e, char* ptr,
167
+ uint32_t val, int min, int max) {
168
+ int shift = _upb_Log2Ceiling(upb_FromBase92(max) - upb_FromBase92(min) + 1);
169
+ UPB_ASSERT(shift <= 6);
170
+ uint32_t mask = (1 << shift) - 1;
171
+ do {
172
+ uint32_t bits = val & mask;
173
+ ptr = upb_MtDataEncoder_Put(e, ptr, bits + upb_FromBase92(min));
174
+ if (!ptr) return NULL;
175
+ val >>= shift;
176
+ } while (val);
177
+ return ptr;
178
+ }
179
+
180
+ char* upb_MtDataEncoder_PutModifier(upb_MtDataEncoder* e, char* ptr,
181
+ uint64_t mod) {
182
+ if (mod) {
183
+ ptr = upb_MtDataEncoder_PutBase92Varint(e, ptr, mod,
184
+ kUpb_EncodedValue_MinModifier,
185
+ kUpb_EncodedValue_MaxModifier);
186
+ }
187
+ return ptr;
188
+ }
189
+
190
+ char* upb_MtDataEncoder_StartMessage(upb_MtDataEncoder* e, char* ptr,
191
+ uint64_t msg_mod) {
192
+ upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
193
+ in->state.msg_state.msg_modifiers = msg_mod;
194
+ in->state.msg_state.last_field_num = 0;
195
+ in->state.msg_state.oneof_state = kUpb_OneofState_NotStarted;
196
+ return upb_MtDataEncoder_PutModifier(e, ptr, msg_mod);
197
+ }
198
+
199
+ char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr,
200
+ upb_FieldType type, uint32_t field_num,
201
+ uint64_t field_mod) {
202
+ static const char kUpb_TypeToEncoded[] = {
203
+ [kUpb_FieldType_Double] = kUpb_EncodedType_Double,
204
+ [kUpb_FieldType_Float] = kUpb_EncodedType_Float,
205
+ [kUpb_FieldType_Int64] = kUpb_EncodedType_Int64,
206
+ [kUpb_FieldType_UInt64] = kUpb_EncodedType_UInt64,
207
+ [kUpb_FieldType_Int32] = kUpb_EncodedType_Int32,
208
+ [kUpb_FieldType_Fixed64] = kUpb_EncodedType_Fixed64,
209
+ [kUpb_FieldType_Fixed32] = kUpb_EncodedType_Fixed32,
210
+ [kUpb_FieldType_Bool] = kUpb_EncodedType_Bool,
211
+ [kUpb_FieldType_String] = kUpb_EncodedType_String,
212
+ [kUpb_FieldType_Group] = kUpb_EncodedType_Group,
213
+ [kUpb_FieldType_Message] = kUpb_EncodedType_Message,
214
+ [kUpb_FieldType_Bytes] = kUpb_EncodedType_Bytes,
215
+ [kUpb_FieldType_UInt32] = kUpb_EncodedType_UInt32,
216
+ [kUpb_FieldType_Enum] = kUpb_EncodedType_Enum,
217
+ [kUpb_FieldType_SFixed32] = kUpb_EncodedType_SFixed32,
218
+ [kUpb_FieldType_SFixed64] = kUpb_EncodedType_SFixed64,
219
+ [kUpb_FieldType_SInt32] = kUpb_EncodedType_SInt32,
220
+ [kUpb_FieldType_SInt64] = kUpb_EncodedType_SInt64,
221
+ };
222
+
223
+ upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
224
+ if (field_num <= in->state.msg_state.last_field_num) return NULL;
225
+ if (in->state.msg_state.last_field_num + 1 != field_num) {
226
+ // Put skip.
227
+ UPB_ASSERT(field_num > in->state.msg_state.last_field_num);
228
+ uint32_t skip = field_num - in->state.msg_state.last_field_num;
229
+ ptr = upb_MtDataEncoder_PutBase92Varint(
230
+ e, ptr, skip, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip);
231
+ if (!ptr) return NULL;
232
+ }
233
+ in->state.msg_state.last_field_num = field_num;
234
+
235
+ uint32_t encoded_modifiers = 0;
236
+
237
+ // Put field type.
238
+ if (type == kUpb_FieldType_Enum &&
239
+ !(field_mod & kUpb_FieldModifier_IsClosedEnum)) {
240
+ type = kUpb_FieldType_Int32;
241
+ }
242
+
243
+ int encoded_type = kUpb_TypeToEncoded[type];
244
+ if (field_mod & kUpb_FieldModifier_IsRepeated) {
245
+ // Repeated fields shift the type number up (unlike other modifiers which
246
+ // are bit flags).
247
+ encoded_type += kUpb_EncodedType_RepeatedBase;
248
+
249
+ if (upb_IsTypePackable(type)) {
250
+ bool field_is_packed = field_mod & kUpb_FieldModifier_IsPacked;
251
+ bool default_is_packed = in->state.msg_state.msg_modifiers &
252
+ kUpb_MessageModifier_DefaultIsPacked;
253
+ if (field_is_packed != default_is_packed) {
254
+ encoded_modifiers |= kUpb_EncodedFieldModifier_FlipPacked;
255
+ }
256
+ }
257
+ }
258
+ ptr = upb_MtDataEncoder_Put(e, ptr, encoded_type);
259
+ if (!ptr) return NULL;
260
+
261
+ if (field_mod & kUpb_FieldModifier_IsProto3Singular) {
262
+ encoded_modifiers |= kUpb_EncodedFieldModifier_IsProto3Singular;
263
+ }
264
+ if (field_mod & kUpb_FieldModifier_IsRequired) {
265
+ encoded_modifiers |= kUpb_EncodedFieldModifier_IsRequired;
266
+ }
267
+ return upb_MtDataEncoder_PutModifier(e, ptr, encoded_modifiers);
268
+ }
269
+
270
+ char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* ptr) {
271
+ upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
272
+ if (in->state.msg_state.oneof_state == kUpb_OneofState_NotStarted) {
273
+ ptr = upb_MtDataEncoder_Put(e, ptr, upb_FromBase92(kUpb_EncodedValue_End));
274
+ } else {
275
+ ptr = upb_MtDataEncoder_Put(
276
+ e, ptr, upb_FromBase92(kUpb_EncodedValue_OneofSeparator));
277
+ }
278
+ in->state.msg_state.oneof_state = kUpb_OneofState_StartedOneof;
279
+ return ptr;
280
+ }
281
+
282
+ char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* ptr,
283
+ uint32_t field_num) {
284
+ upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
285
+ if (in->state.msg_state.oneof_state == kUpb_OneofState_EmittedOneofField) {
286
+ ptr = upb_MtDataEncoder_Put(
287
+ e, ptr, upb_FromBase92(kUpb_EncodedValue_FieldSeparator));
288
+ if (!ptr) return NULL;
289
+ }
290
+ ptr = upb_MtDataEncoder_PutBase92Varint(e, ptr, field_num, upb_ToBase92(0),
291
+ upb_ToBase92(63));
292
+ in->state.msg_state.oneof_state = kUpb_OneofState_EmittedOneofField;
293
+ return ptr;
294
+ }
295
+
296
+ void upb_MtDataEncoder_StartEnum(upb_MtDataEncoder* e) {
297
+ upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, NULL);
298
+ in->state.enum_state.present_values_mask = 0;
299
+ in->state.enum_state.last_written_value = 0;
300
+ }
301
+
302
+ static char* upb_MtDataEncoder_FlushDenseEnumMask(upb_MtDataEncoder* e,
303
+ char* ptr) {
304
+ upb_MtDataEncoderInternal* in = (upb_MtDataEncoderInternal*)e->internal;
305
+ ptr = upb_MtDataEncoder_Put(e, ptr, in->state.enum_state.present_values_mask);
306
+ in->state.enum_state.present_values_mask = 0;
307
+ in->state.enum_state.last_written_value += 5;
308
+ return ptr;
309
+ }
310
+
311
+ char* upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder* e, char* ptr,
312
+ uint32_t val) {
313
+ // TODO(b/229641772): optimize this encoding.
314
+ upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
315
+ UPB_ASSERT(val >= in->state.enum_state.last_written_value);
316
+ uint32_t delta = val - in->state.enum_state.last_written_value;
317
+ if (delta >= 5 && in->state.enum_state.present_values_mask) {
318
+ ptr = upb_MtDataEncoder_FlushDenseEnumMask(e, ptr);
319
+ delta -= 5;
320
+ }
321
+
322
+ if (delta >= 5) {
323
+ ptr = upb_MtDataEncoder_PutBase92Varint(
324
+ e, ptr, delta, kUpb_EncodedValue_MinSkip, kUpb_EncodedValue_MaxSkip);
325
+ in->state.enum_state.last_written_value += delta;
326
+ delta = 0;
327
+ }
328
+
329
+ UPB_ASSERT((in->state.enum_state.present_values_mask >> delta) == 0);
330
+ in->state.enum_state.present_values_mask |= 1ULL << delta;
331
+ return ptr;
332
+ }
333
+
334
+ char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr) {
335
+ upb_MtDataEncoderInternal* in = upb_MtDataEncoder_GetInternal(e, ptr);
336
+ if (!in->state.enum_state.present_values_mask) return ptr;
337
+ return upb_MtDataEncoder_FlushDenseEnumMask(e, ptr);
338
+ }
339
+
340
+ const upb_MiniTable_Field* upb_MiniTable_FindFieldByNumber(
341
+ const upb_MiniTable* table, uint32_t number) {
342
+ int n = table->field_count;
343
+ for (int i = 0; i < n; i++) {
344
+ if (table->fields[i].number == number) {
345
+ return &table->fields[i];
346
+ }
347
+ }
348
+ return NULL;
349
+ }
350
+
351
+ /** Data decoder **************************************************************/
352
+
353
+ // Note: we sort by this number when calculating layout order.
354
+ typedef enum {
355
+ kUpb_LayoutItemType_OneofCase, // Oneof case.
356
+ kUpb_LayoutItemType_OneofField, // Oneof field data.
357
+ kUpb_LayoutItemType_Field, // Non-oneof field data.
358
+
359
+ kUpb_LayoutItemType_Max = kUpb_LayoutItemType_Field,
360
+ } upb_LayoutItemType;
361
+
362
+ #define kUpb_LayoutItem_IndexSentinel ((uint16_t)-1)
363
+
364
+ typedef struct {
365
+ // Index of the corresponding field. When this is a oneof field, the field's
366
+ // offset will be the index of the next field in a linked list.
367
+ uint16_t field_index;
368
+ uint16_t offset;
369
+ upb_FieldRep rep;
370
+ upb_LayoutItemType type;
371
+ } upb_LayoutItem;
372
+
373
+ typedef struct {
374
+ upb_LayoutItem* data;
375
+ size_t size;
376
+ size_t capacity;
377
+ } upb_LayoutItemVector;
378
+
379
+ typedef struct {
380
+ const char* end;
381
+ upb_MiniTable* table;
382
+ upb_MiniTable_Field* fields;
383
+ upb_MiniTablePlatform platform;
384
+ upb_LayoutItemVector vec;
385
+ upb_Arena* arena;
386
+ upb_Status* status;
387
+ jmp_buf err;
388
+ } upb_MtDecoder;
389
+
390
+ UPB_PRINTF(2, 3)
391
+ UPB_NORETURN static void upb_MtDecoder_ErrorFormat(upb_MtDecoder* d,
392
+ const char* fmt, ...) {
393
+ va_list argp;
394
+ upb_Status_SetErrorMessage(d->status, "Error building mini table: ");
395
+ va_start(argp, fmt);
396
+ upb_Status_VAppendErrorFormat(d->status, fmt, argp);
397
+ va_end(argp);
398
+ UPB_LONGJMP(d->err, 1);
399
+ }
400
+
401
+ static void upb_MtDecoder_CheckOutOfMemory(upb_MtDecoder* d, const void* ptr) {
402
+ if (!ptr) upb_MtDecoder_ErrorFormat(d, "Out of memory");
403
+ }
404
+
405
+ // In each field's offset, we temporarily store a presence classifier:
406
+ enum PresenceClass {
407
+ kNoPresence = 0,
408
+ kHasbitPresence = 1,
409
+ kRequiredPresence = 2,
410
+ kOneofBase = 3,
411
+ // Negative values refer to a specific oneof with that number. Positive
412
+ // values >= kOneofBase indicate that this field is in a oneof, and specify
413
+ // the next field in this oneof's linked list.
414
+ };
415
+
416
+ static const char* upb_MiniTable_DecodeBase92Varint(upb_MtDecoder* d,
417
+ const char* ptr,
418
+ char first_ch, uint8_t min,
419
+ uint8_t max,
420
+ uint32_t* out_val) {
421
+ uint32_t val = 0;
422
+ uint32_t shift = 0;
423
+ const int bits_per_char =
424
+ _upb_Log2Ceiling(upb_FromBase92(max) - upb_FromBase92(min));
425
+ char ch = first_ch;
426
+ while (1) {
427
+ uint32_t bits = upb_FromBase92(ch) - upb_FromBase92(min);
428
+ UPB_ASSERT(shift < 32);
429
+ val |= bits << shift;
430
+ if (ptr == d->end || *ptr < min || max < *ptr) {
431
+ *out_val = val;
432
+ return ptr;
433
+ }
434
+ ch = *ptr++;
435
+ shift += bits_per_char;
436
+ }
437
+ }
438
+
439
+ static bool upb_MiniTable_HasSub(upb_MiniTable_Field* field,
440
+ uint64_t msg_modifiers) {
441
+ switch (field->descriptortype) {
442
+ case kUpb_FieldType_Message:
443
+ case kUpb_FieldType_Group:
444
+ case kUpb_FieldType_Enum:
445
+ return true;
446
+ case kUpb_FieldType_String:
447
+ if (!(msg_modifiers & kUpb_MessageModifier_ValidateUtf8)) {
448
+ field->descriptortype = kUpb_FieldType_Bytes;
449
+ }
450
+ return false;
451
+ default:
452
+ return false;
453
+ }
454
+ }
455
+
456
+ static bool upb_MtDecoder_FieldIsPackable(upb_MiniTable_Field* field) {
457
+ return (field->mode & kUpb_FieldMode_Array) &&
458
+ upb_IsTypePackable(field->descriptortype);
459
+ }
460
+
461
+ static void upb_MiniTable_SetTypeAndSub(upb_MiniTable_Field* field,
462
+ upb_FieldType type, uint32_t* sub_count,
463
+ uint64_t msg_modifiers) {
464
+ field->descriptortype = type;
465
+ if (upb_MiniTable_HasSub(field, msg_modifiers)) {
466
+ field->submsg_index = sub_count ? (*sub_count)++ : 0;
467
+ } else {
468
+ field->submsg_index = kUpb_NoSub;
469
+ }
470
+
471
+ if (upb_MtDecoder_FieldIsPackable(field) &&
472
+ (msg_modifiers & kUpb_MessageModifier_DefaultIsPacked)) {
473
+ field->mode |= kUpb_LabelFlags_IsPacked;
474
+ }
475
+ }
476
+
477
+ static void upb_MiniTable_SetField(upb_MtDecoder* d, uint8_t ch,
478
+ upb_MiniTable_Field* field,
479
+ uint64_t msg_modifiers,
480
+ uint32_t* sub_count) {
481
+ static const char kUpb_EncodedToFieldRep[] = {
482
+ [kUpb_EncodedType_Double] = kUpb_FieldRep_8Byte,
483
+ [kUpb_EncodedType_Float] = kUpb_FieldRep_4Byte,
484
+ [kUpb_EncodedType_Int64] = kUpb_FieldRep_8Byte,
485
+ [kUpb_EncodedType_UInt64] = kUpb_FieldRep_8Byte,
486
+ [kUpb_EncodedType_Int32] = kUpb_FieldRep_4Byte,
487
+ [kUpb_EncodedType_Fixed64] = kUpb_FieldRep_8Byte,
488
+ [kUpb_EncodedType_Fixed32] = kUpb_FieldRep_4Byte,
489
+ [kUpb_EncodedType_Bool] = kUpb_FieldRep_1Byte,
490
+ [kUpb_EncodedType_String] = kUpb_FieldRep_StringView,
491
+ [kUpb_EncodedType_Group] = kUpb_FieldRep_Pointer,
492
+ [kUpb_EncodedType_Message] = kUpb_FieldRep_Pointer,
493
+ [kUpb_EncodedType_Bytes] = kUpb_FieldRep_StringView,
494
+ [kUpb_EncodedType_UInt32] = kUpb_FieldRep_4Byte,
495
+ [kUpb_EncodedType_Enum] = kUpb_FieldRep_4Byte,
496
+ [kUpb_EncodedType_SFixed32] = kUpb_FieldRep_4Byte,
497
+ [kUpb_EncodedType_SFixed64] = kUpb_FieldRep_8Byte,
498
+ [kUpb_EncodedType_SInt32] = kUpb_FieldRep_4Byte,
499
+ [kUpb_EncodedType_SInt64] = kUpb_FieldRep_8Byte,
500
+ };
501
+
502
+ static const char kUpb_EncodedToType[] = {
503
+ [kUpb_EncodedType_Double] = kUpb_FieldType_Double,
504
+ [kUpb_EncodedType_Float] = kUpb_FieldType_Float,
505
+ [kUpb_EncodedType_Int64] = kUpb_FieldType_Int64,
506
+ [kUpb_EncodedType_UInt64] = kUpb_FieldType_UInt64,
507
+ [kUpb_EncodedType_Int32] = kUpb_FieldType_Int32,
508
+ [kUpb_EncodedType_Fixed64] = kUpb_FieldType_Fixed64,
509
+ [kUpb_EncodedType_Fixed32] = kUpb_FieldType_Fixed32,
510
+ [kUpb_EncodedType_Bool] = kUpb_FieldType_Bool,
511
+ [kUpb_EncodedType_String] = kUpb_FieldType_String,
512
+ [kUpb_EncodedType_Group] = kUpb_FieldType_Group,
513
+ [kUpb_EncodedType_Message] = kUpb_FieldType_Message,
514
+ [kUpb_EncodedType_Bytes] = kUpb_FieldType_Bytes,
515
+ [kUpb_EncodedType_UInt32] = kUpb_FieldType_UInt32,
516
+ [kUpb_EncodedType_Enum] = kUpb_FieldType_Enum,
517
+ [kUpb_EncodedType_SFixed32] = kUpb_FieldType_SFixed32,
518
+ [kUpb_EncodedType_SFixed64] = kUpb_FieldType_SFixed64,
519
+ [kUpb_EncodedType_SInt32] = kUpb_FieldType_SInt32,
520
+ [kUpb_EncodedType_SInt64] = kUpb_FieldType_SInt64,
521
+ };
522
+
523
+ int8_t type = upb_FromBase92(ch);
524
+ if (ch >= upb_ToBase92(kUpb_EncodedType_RepeatedBase)) {
525
+ type -= kUpb_EncodedType_RepeatedBase;
526
+ field->mode = kUpb_FieldMode_Array;
527
+ field->mode |= kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift;
528
+ field->offset = kNoPresence;
529
+ } else {
530
+ field->mode = kUpb_FieldMode_Scalar;
531
+ field->mode |= kUpb_EncodedToFieldRep[type] << kUpb_FieldRep_Shift;
532
+ field->offset = kHasbitPresence;
533
+ }
534
+ if (type >= 18) {
535
+ upb_MtDecoder_ErrorFormat(d, "Invalid field type: %d", (int)type);
536
+ UPB_UNREACHABLE();
537
+ }
538
+ upb_MiniTable_SetTypeAndSub(field, kUpb_EncodedToType[type], sub_count,
539
+ msg_modifiers);
540
+ }
541
+
542
+ static void upb_MtDecoder_ModifyField(upb_MtDecoder* d,
543
+ uint32_t message_modifiers,
544
+ uint32_t field_modifiers,
545
+ upb_MiniTable_Field* field) {
546
+ if (field_modifiers & kUpb_EncodedFieldModifier_FlipPacked) {
547
+ if (!upb_MtDecoder_FieldIsPackable(field)) {
548
+ upb_MtDecoder_ErrorFormat(
549
+ d, "Cannot flip packed on unpackable field %" PRIu32, field->number);
550
+ UPB_UNREACHABLE();
551
+ }
552
+ field->mode ^= kUpb_LabelFlags_IsPacked;
553
+ }
554
+
555
+ bool singular = field_modifiers & kUpb_EncodedFieldModifier_IsProto3Singular;
556
+ bool required = field_modifiers & kUpb_EncodedFieldModifier_IsRequired;
557
+
558
+ // Validate.
559
+ if ((singular || required) && field->offset != kHasbitPresence) {
560
+ upb_MtDecoder_ErrorFormat(
561
+ d, "Invalid modifier(s) for repeated field %" PRIu32, field->number);
562
+ UPB_UNREACHABLE();
563
+ }
564
+ if (singular && required) {
565
+ upb_MtDecoder_ErrorFormat(
566
+ d, "Field %" PRIu32 " cannot be both singular and required",
567
+ field->number);
568
+ UPB_UNREACHABLE();
569
+ }
570
+
571
+ if (singular) field->offset = kNoPresence;
572
+ if (required) {
573
+ field->offset = kRequiredPresence;
574
+ }
575
+ }
576
+
577
+ static void upb_MtDecoder_PushItem(upb_MtDecoder* d, upb_LayoutItem item) {
578
+ if (d->vec.size == d->vec.capacity) {
579
+ size_t new_cap = UPB_MAX(8, d->vec.size * 2);
580
+ d->vec.data = realloc(d->vec.data, new_cap * sizeof(*d->vec.data));
581
+ upb_MtDecoder_CheckOutOfMemory(d, d->vec.data);
582
+ d->vec.capacity = new_cap;
583
+ }
584
+ d->vec.data[d->vec.size++] = item;
585
+ }
586
+
587
+ static void upb_MtDecoder_PushOneof(upb_MtDecoder* d, upb_LayoutItem item) {
588
+ if (item.field_index == kUpb_LayoutItem_IndexSentinel) {
589
+ upb_MtDecoder_ErrorFormat(d, "Empty oneof");
590
+ UPB_UNREACHABLE();
591
+ }
592
+ item.field_index -= kOneofBase;
593
+
594
+ // Push oneof data.
595
+ item.type = kUpb_LayoutItemType_OneofField;
596
+ upb_MtDecoder_PushItem(d, item);
597
+
598
+ // Push oneof case.
599
+ item.rep = kUpb_FieldRep_4Byte; // Field Number.
600
+ item.type = kUpb_LayoutItemType_OneofCase;
601
+ upb_MtDecoder_PushItem(d, item);
602
+ }
603
+
604
+ size_t upb_MtDecoder_SizeOfRep(upb_FieldRep rep,
605
+ upb_MiniTablePlatform platform) {
606
+ static const uint8_t kRepToSize32[] = {
607
+ [kUpb_FieldRep_1Byte] = 1, [kUpb_FieldRep_4Byte] = 4,
608
+ [kUpb_FieldRep_Pointer] = 4, [kUpb_FieldRep_StringView] = 8,
609
+ [kUpb_FieldRep_8Byte] = 8,
610
+ };
611
+ static const uint8_t kRepToSize64[] = {
612
+ [kUpb_FieldRep_1Byte] = 1, [kUpb_FieldRep_4Byte] = 4,
613
+ [kUpb_FieldRep_Pointer] = 8, [kUpb_FieldRep_StringView] = 16,
614
+ [kUpb_FieldRep_8Byte] = 8,
615
+ };
616
+ UPB_ASSERT(sizeof(upb_StringView) ==
617
+ UPB_SIZE(kRepToSize32, kRepToSize64)[kUpb_FieldRep_StringView]);
618
+ return platform == kUpb_MiniTablePlatform_32Bit ? kRepToSize32[rep]
619
+ : kRepToSize64[rep];
620
+ }
621
+
622
+ size_t upb_MtDecoder_AlignOfRep(upb_FieldRep rep,
623
+ upb_MiniTablePlatform platform) {
624
+ static const uint8_t kRepToAlign32[] = {
625
+ [kUpb_FieldRep_1Byte] = 1, [kUpb_FieldRep_4Byte] = 4,
626
+ [kUpb_FieldRep_Pointer] = 4, [kUpb_FieldRep_StringView] = 4,
627
+ [kUpb_FieldRep_8Byte] = 8,
628
+ };
629
+ static const uint8_t kRepToAlign64[] = {
630
+ [kUpb_FieldRep_1Byte] = 1, [kUpb_FieldRep_4Byte] = 4,
631
+ [kUpb_FieldRep_Pointer] = 8, [kUpb_FieldRep_StringView] = 8,
632
+ [kUpb_FieldRep_8Byte] = 8,
633
+ };
634
+ UPB_ASSERT(UPB_ALIGN_OF(upb_StringView) ==
635
+ UPB_SIZE(kRepToAlign32, kRepToAlign64)[kUpb_FieldRep_StringView]);
636
+ return platform == kUpb_MiniTablePlatform_32Bit ? kRepToAlign32[rep]
637
+ : kRepToAlign64[rep];
638
+ }
639
+
640
+ static const char* upb_MtDecoder_DecodeOneofField(upb_MtDecoder* d,
641
+ const char* ptr,
642
+ char first_ch,
643
+ upb_LayoutItem* item) {
644
+ uint32_t field_num;
645
+ ptr = upb_MiniTable_DecodeBase92Varint(
646
+ d, ptr, first_ch, kUpb_EncodedValue_MinOneofField,
647
+ kUpb_EncodedValue_MaxOneofField, &field_num);
648
+ upb_MiniTable_Field* f =
649
+ (void*)upb_MiniTable_FindFieldByNumber(d->table, field_num);
650
+
651
+ if (!f) {
652
+ upb_MtDecoder_ErrorFormat(d,
653
+ "Couldn't add field number %" PRIu32
654
+ " to oneof, no such field number.",
655
+ field_num);
656
+ UPB_UNREACHABLE();
657
+ }
658
+ if (f->offset != kHasbitPresence) {
659
+ upb_MtDecoder_ErrorFormat(
660
+ d,
661
+ "Cannot add repeated, required, or singular field %" PRIu32
662
+ " to oneof.",
663
+ field_num);
664
+ UPB_UNREACHABLE();
665
+ }
666
+
667
+ // Oneof storage must be large enough to accommodate the largest member.
668
+ int rep = f->mode >> kUpb_FieldRep_Shift;
669
+ if (upb_MtDecoder_SizeOfRep(rep, d->platform) >
670
+ upb_MtDecoder_SizeOfRep(item->rep, d->platform)) {
671
+ item->rep = rep;
672
+ }
673
+ // Prepend this field to the linked list.
674
+ f->offset = item->field_index;
675
+ item->field_index = (f - d->fields) + kOneofBase;
676
+ return ptr;
677
+ }
678
+
679
+ static const char* upb_MtDecoder_DecodeOneofs(upb_MtDecoder* d,
680
+ const char* ptr) {
681
+ upb_LayoutItem item = {.rep = 0,
682
+ .field_index = kUpb_LayoutItem_IndexSentinel};
683
+ while (ptr < d->end) {
684
+ char ch = *ptr++;
685
+ if (ch == kUpb_EncodedValue_FieldSeparator) {
686
+ // Field separator, no action needed.
687
+ } else if (ch == kUpb_EncodedValue_OneofSeparator) {
688
+ // End of oneof.
689
+ upb_MtDecoder_PushOneof(d, item);
690
+ item.field_index = kUpb_LayoutItem_IndexSentinel; // Move to next oneof.
691
+ } else {
692
+ ptr = upb_MtDecoder_DecodeOneofField(d, ptr, ch, &item);
693
+ }
694
+ }
695
+
696
+ // Push final oneof.
697
+ upb_MtDecoder_PushOneof(d, item);
698
+ return ptr;
699
+ }
700
+
701
+ static const char* upb_MtDecoder_ParseModifier(upb_MtDecoder* d,
702
+ const char* ptr, char first_ch,
703
+ upb_MiniTable_Field* last_field,
704
+ uint64_t* msg_modifiers) {
705
+ uint32_t mod;
706
+ ptr = upb_MiniTable_DecodeBase92Varint(d, ptr, first_ch,
707
+ kUpb_EncodedValue_MinModifier,
708
+ kUpb_EncodedValue_MaxModifier, &mod);
709
+ if (last_field) {
710
+ upb_MtDecoder_ModifyField(d, *msg_modifiers, mod, last_field);
711
+ } else {
712
+ if (!d->table) {
713
+ upb_MtDecoder_ErrorFormat(d, "Extensions cannot have message modifiers");
714
+ UPB_UNREACHABLE();
715
+ }
716
+ *msg_modifiers = mod;
717
+ }
718
+
719
+ return ptr;
720
+ }
721
+
722
+ static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d, uint32_t sub_count) {
723
+ size_t subs_bytes = sizeof(*d->table->subs) * sub_count;
724
+ d->table->subs = upb_Arena_Malloc(d->arena, subs_bytes);
725
+ upb_MtDecoder_CheckOutOfMemory(d, d->table->subs);
726
+ }
727
+
728
+ static void upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, size_t len,
729
+ void* fields, size_t field_size,
730
+ uint16_t* field_count, uint32_t* sub_count) {
731
+ uint64_t msg_modifiers = 0;
732
+ uint32_t last_field_number = 0;
733
+ upb_MiniTable_Field* last_field = NULL;
734
+ bool need_dense_below = d->table != NULL;
735
+
736
+ d->end = UPB_PTRADD(ptr, len);
737
+
738
+ while (ptr < d->end) {
739
+ char ch = *ptr++;
740
+ if (ch <= kUpb_EncodedValue_MaxField) {
741
+ upb_MiniTable_Field* field = fields;
742
+ *field_count += 1;
743
+ fields = (char*)fields + field_size;
744
+ field->number = ++last_field_number;
745
+ last_field = field;
746
+ upb_MiniTable_SetField(d, ch, field, msg_modifiers, sub_count);
747
+ } else if (kUpb_EncodedValue_MinModifier <= ch &&
748
+ ch <= kUpb_EncodedValue_MaxModifier) {
749
+ ptr = upb_MtDecoder_ParseModifier(d, ptr, ch, last_field, &msg_modifiers);
750
+ } else if (ch == kUpb_EncodedValue_End) {
751
+ if (!d->table) {
752
+ upb_MtDecoder_ErrorFormat(d, "Extensions cannot have oneofs.");
753
+ UPB_UNREACHABLE();
754
+ }
755
+ ptr = upb_MtDecoder_DecodeOneofs(d, ptr);
756
+ } else if (kUpb_EncodedValue_MinSkip <= ch &&
757
+ ch <= kUpb_EncodedValue_MaxSkip) {
758
+ if (need_dense_below) {
759
+ d->table->dense_below = d->table->field_count;
760
+ need_dense_below = false;
761
+ }
762
+ uint32_t skip;
763
+ ptr = upb_MiniTable_DecodeBase92Varint(d, ptr, ch,
764
+ kUpb_EncodedValue_MinSkip,
765
+ kUpb_EncodedValue_MaxSkip, &skip);
766
+ last_field_number += skip;
767
+ last_field_number--; // Next field seen will increment.
768
+ }
769
+ }
770
+
771
+ if (need_dense_below) {
772
+ d->table->dense_below = d->table->field_count;
773
+ }
774
+ }
775
+
776
+ static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data,
777
+ size_t len) {
778
+ // Buffer length is an upper bound on the number of fields. We will return
779
+ // what we don't use.
780
+ d->fields = upb_Arena_Malloc(d->arena, sizeof(*d->fields) * len);
781
+ upb_MtDecoder_CheckOutOfMemory(d, d->fields);
782
+
783
+ uint32_t sub_count = 0;
784
+ d->table->field_count = 0;
785
+ d->table->fields = d->fields;
786
+ upb_MtDecoder_Parse(d, data, len, d->fields, sizeof(*d->fields),
787
+ &d->table->field_count, &sub_count);
788
+
789
+ upb_Arena_ShrinkLast(d->arena, d->fields, sizeof(*d->fields) * len,
790
+ sizeof(*d->fields) * d->table->field_count);
791
+ d->table->fields = d->fields;
792
+ upb_MtDecoder_AllocateSubs(d, sub_count);
793
+ }
794
+
795
+ int upb_MtDecoder_CompareFields(const void* _a, const void* _b) {
796
+ const upb_LayoutItem* a = _a;
797
+ const upb_LayoutItem* b = _b;
798
+ // Currently we just sort by:
799
+ // 1. rep (smallest fields first)
800
+ // 2. type (oneof cases first)
801
+ // 2. field_index (smallest numbers first)
802
+ // The main goal of this is to reduce space lost to padding.
803
+ // Later we may have more subtle reasons to prefer a different ordering.
804
+ const int rep_bits = _upb_Log2Ceiling(kUpb_FieldRep_Max);
805
+ const int type_bits = _upb_Log2Ceiling(kUpb_LayoutItemType_Max);
806
+ const int idx_bits = (sizeof(a->field_index) * 8);
807
+ UPB_ASSERT(idx_bits + rep_bits + type_bits < 32);
808
+ #define UPB_COMBINE(rep, ty, idx) (((rep << type_bits) | ty) << idx_bits) | idx
809
+ uint32_t a_packed = UPB_COMBINE(a->rep, a->type, a->field_index);
810
+ uint32_t b_packed = UPB_COMBINE(b->rep, b->type, b->field_index);
811
+ assert(a_packed != b_packed);
812
+ #undef UPB_COMBINE
813
+ return a_packed < b_packed ? -1 : 1;
814
+ }
815
+
816
+ static bool upb_MtDecoder_SortLayoutItems(upb_MtDecoder* d) {
817
+ // Add items for all non-oneof fields (oneofs were already added).
818
+ int n = d->table->field_count;
819
+ for (int i = 0; i < n; i++) {
820
+ upb_MiniTable_Field* f = &d->fields[i];
821
+ if (f->offset >= kOneofBase) continue;
822
+ upb_LayoutItem item = {.field_index = i,
823
+ .rep = f->mode >> kUpb_FieldRep_Shift,
824
+ .type = kUpb_LayoutItemType_Field};
825
+ upb_MtDecoder_PushItem(d, item);
826
+ }
827
+
828
+ if (d->vec.size) {
829
+ qsort(d->vec.data, d->vec.size, sizeof(*d->vec.data),
830
+ upb_MtDecoder_CompareFields);
831
+ }
832
+
833
+ return true;
834
+ }
835
+
836
+ static size_t upb_MiniTable_DivideRoundUp(size_t n, size_t d) {
837
+ return (n + d - 1) / d;
838
+ }
839
+
840
+ static void upb_MtDecoder_AssignHasbits(upb_MiniTable* ret) {
841
+ int n = ret->field_count;
842
+ int last_hasbit = 0; // 0 cannot be used.
843
+
844
+ // First assign required fields, which must have the lowest hasbits.
845
+ for (int i = 0; i < n; i++) {
846
+ upb_MiniTable_Field* field = (upb_MiniTable_Field*)&ret->fields[i];
847
+ if (field->offset == kRequiredPresence) {
848
+ field->presence = ++last_hasbit;
849
+ } else if (field->offset == kNoPresence) {
850
+ field->presence = 0;
851
+ }
852
+ }
853
+ ret->required_count = last_hasbit;
854
+
855
+ // Next assign non-required hasbit fields.
856
+ for (int i = 0; i < n; i++) {
857
+ upb_MiniTable_Field* field = (upb_MiniTable_Field*)&ret->fields[i];
858
+ if (field->offset == kHasbitPresence) {
859
+ field->presence = ++last_hasbit;
860
+ }
861
+ }
862
+
863
+ ret->size = last_hasbit ? upb_MiniTable_DivideRoundUp(last_hasbit + 1, 8) : 0;
864
+ }
865
+
866
+ size_t upb_MtDecoder_Place(upb_MtDecoder* d, upb_FieldRep rep) {
867
+ size_t size = upb_MtDecoder_SizeOfRep(rep, d->platform);
868
+ size_t align = upb_MtDecoder_AlignOfRep(rep, d->platform);
869
+ size_t ret = UPB_ALIGN_UP(d->table->size, align);
870
+ d->table->size = ret + size;
871
+ return ret;
872
+ }
873
+
874
+ static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) {
875
+ upb_LayoutItem* end = UPB_PTRADD(d->vec.data, d->vec.size);
876
+
877
+ // Compute offsets.
878
+ for (upb_LayoutItem* item = d->vec.data; item < end; item++) {
879
+ item->offset = upb_MtDecoder_Place(d, item->rep);
880
+ }
881
+
882
+ // Assign oneof case offsets. We must do these first, since assigning
883
+ // actual offsets will overwrite the links of the linked list.
884
+ for (upb_LayoutItem* item = d->vec.data; item < end; item++) {
885
+ if (item->type != kUpb_LayoutItemType_OneofCase) continue;
886
+ upb_MiniTable_Field* f = &d->fields[item->field_index];
887
+ while (true) {
888
+ f->presence = ~item->offset;
889
+ if (f->offset == kUpb_LayoutItem_IndexSentinel) break;
890
+ UPB_ASSERT(f->offset - kOneofBase < d->table->field_count);
891
+ f = &d->fields[f->offset - kOneofBase];
892
+ }
893
+ }
894
+
895
+ // Assign offsets.
896
+ for (upb_LayoutItem* item = d->vec.data; item < end; item++) {
897
+ upb_MiniTable_Field* f = &d->fields[item->field_index];
898
+ switch (item->type) {
899
+ case kUpb_LayoutItemType_OneofField:
900
+ while (true) {
901
+ uint16_t next_offset = f->offset;
902
+ f->offset = item->offset;
903
+ if (next_offset == kUpb_LayoutItem_IndexSentinel) break;
904
+ f = &d->fields[next_offset - kOneofBase];
905
+ }
906
+ break;
907
+ case kUpb_LayoutItemType_Field:
908
+ f->offset = item->offset;
909
+ break;
910
+ default:
911
+ break;
912
+ }
913
+ }
914
+
915
+ if (d->platform == kUpb_MiniTablePlatform_64Bit) {
916
+ // For compatibility with fast table parsing, we have to align this up to a
917
+ // multiple of 16 + 8. This is because arena alloc size must be a multiple
918
+ // of 16, but we will add sizeof(upb_Message_Internal) at runtime, as the
919
+ // table size does not include this value.
920
+ //
921
+ // This is a bit convoluted and should probably be simplified.
922
+ d->table->size = UPB_ALIGN_UP(d->table->size, 8);
923
+ if (UPB_ALIGN_UP(d->table->size, 16) == d->table->size) {
924
+ d->table->size += 8;
925
+ }
926
+ }
927
+ }
928
+
929
+ upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len,
930
+ upb_MiniTablePlatform platform,
931
+ upb_Arena* arena, void** buf,
932
+ size_t* buf_size,
933
+ upb_Status* status) {
934
+ upb_MtDecoder decoder = {
935
+ .platform = platform,
936
+ .vec =
937
+ {
938
+ .data = *buf,
939
+ .capacity = *buf_size / sizeof(*decoder.vec.data),
940
+ .size = 0,
941
+ },
942
+ .arena = arena,
943
+ .status = status,
944
+ .table = upb_Arena_Malloc(arena, sizeof(*decoder.table)),
945
+ };
946
+
947
+ if (UPB_SETJMP(decoder.err)) {
948
+ decoder.table = NULL;
949
+ goto done;
950
+ }
951
+
952
+ upb_MtDecoder_CheckOutOfMemory(&decoder, decoder.table);
953
+
954
+ decoder.table->size = 0;
955
+ decoder.table->field_count = 0;
956
+ decoder.table->ext = kUpb_ExtMode_NonExtendable;
957
+ decoder.table->dense_below = 0;
958
+ decoder.table->table_mask = 0;
959
+ decoder.table->required_count = 0;
960
+
961
+ upb_MtDecoder_ParseMessage(&decoder, data, len);
962
+ upb_MtDecoder_AssignHasbits(decoder.table);
963
+ upb_MtDecoder_SortLayoutItems(&decoder);
964
+ upb_MtDecoder_AssignOffsets(&decoder);
965
+
966
+ done:
967
+ *buf = decoder.vec.data;
968
+ *buf_size = decoder.vec.capacity / sizeof(*decoder.vec.data);
969
+ return decoder.table;
970
+ }
971
+
972
+ upb_MiniTable* upb_MiniTable_BuildMessageSet(upb_MiniTablePlatform platform,
973
+ upb_Arena* arena) {
974
+ upb_MiniTable* ret = upb_Arena_Malloc(arena, sizeof(*ret));
975
+ if (!ret) return NULL;
976
+
977
+ ret->size = 0;
978
+ ret->field_count = 0;
979
+ ret->ext = kUpb_ExtMode_IsMessageSet;
980
+ ret->dense_below = 0;
981
+ ret->table_mask = 0;
982
+ ret->required_count = 0;
983
+ return ret;
984
+ }
985
+
986
+ upb_MiniTable* upb_MiniTable_BuildMapEntry(upb_FieldType key_type,
987
+ upb_FieldType value_type,
988
+ bool value_is_proto3_enum,
989
+ upb_MiniTablePlatform platform,
990
+ upb_Arena* arena) {
991
+ upb_MiniTable* ret = upb_Arena_Malloc(arena, sizeof(*ret));
992
+ upb_MiniTable_Field* fields = upb_Arena_Malloc(arena, sizeof(*fields) * 2);
993
+ if (!ret || !fields) return NULL;
994
+
995
+ upb_MiniTable_Sub* subs = NULL;
996
+ if (value_is_proto3_enum) value_type = kUpb_FieldType_Int32;
997
+ if (value_type == kUpb_FieldType_Message ||
998
+ value_type == kUpb_FieldType_Group || value_type == kUpb_FieldType_Enum) {
999
+ subs = upb_Arena_Malloc(arena, sizeof(*subs));
1000
+ if (!subs) return NULL;
1001
+ }
1002
+
1003
+ size_t field_size =
1004
+ upb_MtDecoder_SizeOfRep(kUpb_FieldRep_StringView, platform);
1005
+
1006
+ fields[0].number = 1;
1007
+ fields[1].number = 2;
1008
+ fields[0].mode = kUpb_FieldMode_Scalar;
1009
+ fields[1].mode = kUpb_FieldMode_Scalar;
1010
+ fields[0].presence = 0;
1011
+ fields[1].presence = 0;
1012
+ fields[0].offset = 0;
1013
+ fields[1].offset = field_size;
1014
+
1015
+ upb_MiniTable_SetTypeAndSub(&fields[0], key_type, NULL, 0);
1016
+ upb_MiniTable_SetTypeAndSub(&fields[1], value_type, NULL, 0);
1017
+
1018
+ ret->size = UPB_ALIGN_UP(2 * field_size, 8);
1019
+ ret->field_count = 2;
1020
+ ret->ext = kUpb_ExtMode_NonExtendable | kUpb_ExtMode_IsMapEntry;
1021
+ ret->dense_below = 2;
1022
+ ret->table_mask = 0;
1023
+ ret->required_count = 0;
1024
+ ret->subs = subs;
1025
+ ret->fields = fields;
1026
+ return ret;
1027
+ }
1028
+
1029
+ static bool upb_MiniTable_BuildEnumValue(upb_MtDecoder* d,
1030
+ upb_MiniTable_Enum* table,
1031
+ uint32_t val, upb_Arena* arena) {
1032
+ if (val < 64) {
1033
+ table->mask |= 1ULL << val;
1034
+ return true;
1035
+ }
1036
+
1037
+ int32_t* values = (void*)table->values;
1038
+ values = upb_Arena_Realloc(arena, values, table->value_count * 4,
1039
+ (table->value_count + 1) * 4);
1040
+ upb_MtDecoder_CheckOutOfMemory(d, values);
1041
+ values[table->value_count++] = (int32_t)val;
1042
+ table->values = values;
1043
+ return true;
1044
+ }
1045
+
1046
+ upb_MiniTable_Enum* upb_MiniTable_BuildEnum(const char* data, size_t len,
1047
+ upb_Arena* arena,
1048
+ upb_Status* status) {
1049
+ upb_MtDecoder d = {
1050
+ .status = status,
1051
+ .end = UPB_PTRADD(data, len),
1052
+ };
1053
+
1054
+ if (UPB_SETJMP(d.err)) {
1055
+ return NULL;
1056
+ }
1057
+
1058
+ upb_MiniTable_Enum* table = upb_Arena_Malloc(arena, sizeof(*table));
1059
+ upb_MtDecoder_CheckOutOfMemory(&d, table);
1060
+
1061
+ table->mask = 0;
1062
+ table->value_count = 0;
1063
+ table->values = NULL;
1064
+
1065
+ const char* ptr = data;
1066
+ uint32_t base = 0;
1067
+
1068
+ while (ptr < d.end) {
1069
+ char ch = *ptr++;
1070
+ if (ch <= kUpb_EncodedValue_MaxEnumMask) {
1071
+ uint32_t mask = upb_FromBase92(ch);
1072
+ for (int i = 0; i < 5; i++, base++, mask >>= 1) {
1073
+ if (mask & 1) {
1074
+ if (!upb_MiniTable_BuildEnumValue(&d, table, base, arena)) {
1075
+ return NULL;
1076
+ }
1077
+ }
1078
+ }
1079
+ } else if (kUpb_EncodedValue_MinSkip <= ch &&
1080
+ ch <= kUpb_EncodedValue_MaxSkip) {
1081
+ uint32_t skip;
1082
+ ptr = upb_MiniTable_DecodeBase92Varint(&d, ptr, ch,
1083
+ kUpb_EncodedValue_MinSkip,
1084
+ kUpb_EncodedValue_MaxSkip, &skip);
1085
+ base += skip;
1086
+ } else {
1087
+ upb_Status_SetErrorFormat(status, "Unexpected character: %c", ch);
1088
+ return NULL;
1089
+ }
1090
+ }
1091
+
1092
+ return table;
1093
+ }
1094
+
1095
+ bool upb_MiniTable_BuildExtension(const char* data, size_t len,
1096
+ upb_MiniTable_Extension* ext,
1097
+ upb_MiniTable_Sub sub, upb_Status* status) {
1098
+ upb_MtDecoder decoder = {
1099
+ .arena = NULL,
1100
+ .status = status,
1101
+ .table = NULL,
1102
+ };
1103
+
1104
+ if (UPB_SETJMP(decoder.err)) {
1105
+ return false;
1106
+ }
1107
+
1108
+ uint16_t count = 0;
1109
+ upb_MtDecoder_Parse(&decoder, data, len, ext, sizeof(*ext), &count, NULL);
1110
+ ext->field.mode |= kUpb_LabelFlags_IsExtension;
1111
+ ext->field.offset = 0;
1112
+ return true;
1113
+ }
1114
+
1115
+ upb_MiniTable* upb_MiniTable_Build(const char* data, size_t len,
1116
+ upb_MiniTablePlatform platform,
1117
+ upb_Arena* arena, upb_Status* status) {
1118
+ void* buf = NULL;
1119
+ size_t size = 0;
1120
+ upb_MiniTable* ret = upb_MiniTable_BuildWithBuf(data, len, platform, arena,
1121
+ &buf, &size, status);
1122
+ free(buf);
1123
+ return ret;
1124
+ }
1125
+
1126
+ void upb_MiniTable_SetSubMessage(upb_MiniTable* table,
1127
+ upb_MiniTable_Field* field,
1128
+ const upb_MiniTable* sub) {
1129
+ UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field &&
1130
+ (uintptr_t)field <
1131
+ (uintptr_t)(table->fields + table->field_count));
1132
+ if (sub->ext & kUpb_ExtMode_IsMapEntry) {
1133
+ field->mode =
1134
+ (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift) | kUpb_FieldMode_Map;
1135
+ }
1136
+ upb_MiniTable_Sub* table_sub = (void*)&table->subs[field->submsg_index];
1137
+ table_sub->submsg = sub;
1138
+ }
1139
+
1140
+ void upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTable_Field* field,
1141
+ const upb_MiniTable_Enum* sub) {
1142
+ UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field &&
1143
+ (uintptr_t)field <
1144
+ (uintptr_t)(table->fields + table->field_count));
1145
+ upb_MiniTable_Sub* table_sub = (void*)&table->subs[field->submsg_index];
1146
+ table_sub->subenum = sub;
1147
+ }