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,3262 @@
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/def.h"
29
+
30
+ #include <ctype.h>
31
+ #include <errno.h>
32
+ #include <setjmp.h>
33
+ #include <stdlib.h>
34
+ #include <string.h>
35
+
36
+ #include "google/protobuf/descriptor.upb.h"
37
+ #include "upb/mini_table.h"
38
+ #include "upb/reflection.h"
39
+
40
+ /* Must be last. */
41
+ #include "upb/port_def.inc"
42
+
43
+ typedef struct {
44
+ size_t len;
45
+ char str[1]; /* Null-terminated string data follows. */
46
+ } str_t;
47
+
48
+ /* The upb core does not generally have a concept of default instances. However
49
+ * for descriptor options we make an exception since the max size is known and
50
+ * modest (<200 bytes). All types can share a default instance since it is
51
+ * initialized to zeroes.
52
+ *
53
+ * We have to allocate an extra pointer for upb's internal metadata. */
54
+ static const char opt_default_buf[_UPB_MAXOPT_SIZE + sizeof(void*)] = {0};
55
+ static const char* opt_default = &opt_default_buf[sizeof(void*)];
56
+
57
+ struct upb_FieldDef {
58
+ const google_protobuf_FieldOptions* opts;
59
+ const upb_FileDef* file;
60
+ const upb_MessageDef* msgdef;
61
+ const char* full_name;
62
+ const char* json_name;
63
+ union {
64
+ int64_t sint;
65
+ uint64_t uint;
66
+ double dbl;
67
+ float flt;
68
+ bool boolean;
69
+ str_t* str;
70
+ } defaultval;
71
+ union {
72
+ const upb_OneofDef* oneof;
73
+ const upb_MessageDef* extension_scope;
74
+ } scope;
75
+ union {
76
+ const upb_MessageDef* msgdef;
77
+ const upb_EnumDef* enumdef;
78
+ const google_protobuf_FieldDescriptorProto* unresolved;
79
+ } sub;
80
+ uint32_t number_;
81
+ uint16_t index_;
82
+ uint16_t layout_index; /* Index into msgdef->layout->fields or file->exts */
83
+ bool has_default;
84
+ bool is_extension_;
85
+ bool packed_;
86
+ bool proto3_optional_;
87
+ bool has_json_name_;
88
+ upb_FieldType type_;
89
+ upb_Label label_;
90
+ #if UINTPTR_MAX == 0xffffffff
91
+ uint32_t padding; // Increase size to a multiple of 8.
92
+ #endif
93
+ };
94
+
95
+ struct upb_ExtensionRange {
96
+ const google_protobuf_ExtensionRangeOptions* opts;
97
+ int32_t start;
98
+ int32_t end;
99
+ };
100
+
101
+ struct upb_MessageDef {
102
+ const google_protobuf_MessageOptions* opts;
103
+ const upb_MiniTable* layout;
104
+ const upb_FileDef* file;
105
+ const upb_MessageDef* containing_type;
106
+ const char* full_name;
107
+
108
+ /* Tables for looking up fields by number and name. */
109
+ upb_inttable itof;
110
+ upb_strtable ntof;
111
+
112
+ /* All nested defs.
113
+ * MEM: We could save some space here by putting nested defs in a contiguous
114
+ * region and calculating counts from offsets or vice-versa. */
115
+ const upb_FieldDef* fields;
116
+ const upb_OneofDef* oneofs;
117
+ const upb_ExtensionRange* ext_ranges;
118
+ const upb_MessageDef* nested_msgs;
119
+ const upb_EnumDef* nested_enums;
120
+ const upb_FieldDef* nested_exts;
121
+ int field_count;
122
+ int real_oneof_count;
123
+ int oneof_count;
124
+ int ext_range_count;
125
+ int nested_msg_count;
126
+ int nested_enum_count;
127
+ int nested_ext_count;
128
+ bool in_message_set;
129
+ upb_WellKnown well_known_type;
130
+ #if UINTPTR_MAX == 0xffffffff
131
+ uint32_t padding; // Increase size to a multiple of 8.
132
+ #endif
133
+ };
134
+
135
+ struct upb_EnumDef {
136
+ const google_protobuf_EnumOptions* opts;
137
+ const upb_MiniTable_Enum* layout; // Only for proto2.
138
+ const upb_FileDef* file;
139
+ const upb_MessageDef* containing_type; // Could be merged with "file".
140
+ const char* full_name;
141
+ upb_strtable ntoi;
142
+ upb_inttable iton;
143
+ const upb_EnumValueDef* values;
144
+ int value_count;
145
+ int32_t defaultval;
146
+ #if UINTPTR_MAX == 0xffffffff
147
+ uint32_t padding; // Increase size to a multiple of 8.
148
+ #endif
149
+ };
150
+
151
+ struct upb_EnumValueDef {
152
+ const google_protobuf_EnumValueOptions* opts;
153
+ const upb_EnumDef* parent;
154
+ const char* full_name;
155
+ int32_t number;
156
+ };
157
+
158
+ struct upb_OneofDef {
159
+ const google_protobuf_OneofOptions* opts;
160
+ const upb_MessageDef* parent;
161
+ const char* full_name;
162
+ int field_count;
163
+ bool synthetic;
164
+ const upb_FieldDef** fields;
165
+ upb_strtable ntof;
166
+ upb_inttable itof;
167
+ #if UINTPTR_MAX == 0xffffffff
168
+ uint32_t padding; // Increase size to a multiple of 8.
169
+ #endif
170
+ };
171
+
172
+ struct upb_FileDef {
173
+ const google_protobuf_FileOptions* opts;
174
+ const char* name;
175
+ const char* package;
176
+
177
+ const upb_FileDef** deps;
178
+ const int32_t* public_deps;
179
+ const int32_t* weak_deps;
180
+ const upb_MessageDef* top_lvl_msgs;
181
+ const upb_EnumDef* top_lvl_enums;
182
+ const upb_FieldDef* top_lvl_exts;
183
+ const upb_ServiceDef* services;
184
+ const upb_MiniTable_Extension** ext_layouts;
185
+ const upb_DefPool* symtab;
186
+
187
+ int dep_count;
188
+ int public_dep_count;
189
+ int weak_dep_count;
190
+ int top_lvl_msg_count;
191
+ int top_lvl_enum_count;
192
+ int top_lvl_ext_count;
193
+ int service_count;
194
+ int ext_count; /* All exts in the file. */
195
+ upb_Syntax syntax;
196
+ };
197
+
198
+ struct upb_MethodDef {
199
+ const google_protobuf_MethodOptions* opts;
200
+ upb_ServiceDef* service;
201
+ const char* full_name;
202
+ const upb_MessageDef* input_type;
203
+ const upb_MessageDef* output_type;
204
+ int index;
205
+ bool client_streaming;
206
+ bool server_streaming;
207
+ };
208
+
209
+ struct upb_ServiceDef {
210
+ const google_protobuf_ServiceOptions* opts;
211
+ const upb_FileDef* file;
212
+ const char* full_name;
213
+ upb_MethodDef* methods;
214
+ int method_count;
215
+ int index;
216
+ };
217
+
218
+ struct upb_DefPool {
219
+ upb_Arena* arena;
220
+ upb_strtable syms; /* full_name -> packed def ptr */
221
+ upb_strtable files; /* file_name -> upb_FileDef* */
222
+ upb_inttable exts; /* upb_MiniTable_Extension* -> upb_FieldDef* */
223
+ upb_ExtensionRegistry* extreg;
224
+ size_t bytes_loaded;
225
+ };
226
+
227
+ /* Inside a symtab we store tagged pointers to specific def types. */
228
+ typedef enum {
229
+ UPB_DEFTYPE_MASK = 7,
230
+
231
+ /* Only inside symtab table. */
232
+ UPB_DEFTYPE_EXT = 0,
233
+ UPB_DEFTYPE_MSG = 1,
234
+ UPB_DEFTYPE_ENUM = 2,
235
+ UPB_DEFTYPE_ENUMVAL = 3,
236
+ UPB_DEFTYPE_SERVICE = 4,
237
+
238
+ /* Only inside message table. */
239
+ UPB_DEFTYPE_FIELD = 0,
240
+ UPB_DEFTYPE_ONEOF = 1,
241
+ UPB_DEFTYPE_FIELD_JSONNAME = 2,
242
+
243
+ /* Only inside file table. */
244
+ UPB_DEFTYPE_FILE = 0,
245
+ UPB_DEFTYPE_LAYOUT = 1
246
+ } upb_deftype_t;
247
+
248
+ #define FIELD_TYPE_UNSPECIFIED 0
249
+
250
+ static upb_deftype_t deftype(upb_value v) {
251
+ uintptr_t num = (uintptr_t)upb_value_getconstptr(v);
252
+ return num & UPB_DEFTYPE_MASK;
253
+ }
254
+
255
+ static const void* unpack_def(upb_value v, upb_deftype_t type) {
256
+ uintptr_t num = (uintptr_t)upb_value_getconstptr(v);
257
+ return (num & UPB_DEFTYPE_MASK) == type
258
+ ? (const void*)(num & ~UPB_DEFTYPE_MASK)
259
+ : NULL;
260
+ }
261
+
262
+ static upb_value pack_def(const void* ptr, upb_deftype_t type) {
263
+ // Our 3-bit pointer tagging requires all pointers to be multiples of 8.
264
+ // The arena will always yield 8-byte-aligned addresses, however we put
265
+ // the defs into arrays. For each element in the array to be 8-byte-aligned,
266
+ // the sizes of each def type must also be a multiple of 8.
267
+ //
268
+ // If any of these asserts fail, we need to add or remove padding on 32-bit
269
+ // machines (64-bit machines will have 8-byte alignment already due to
270
+ // pointers, which all of these structs have).
271
+ UPB_ASSERT((sizeof(upb_FieldDef) & UPB_DEFTYPE_MASK) == 0);
272
+ UPB_ASSERT((sizeof(upb_MessageDef) & UPB_DEFTYPE_MASK) == 0);
273
+ UPB_ASSERT((sizeof(upb_EnumDef) & UPB_DEFTYPE_MASK) == 0);
274
+ UPB_ASSERT((sizeof(upb_EnumValueDef) & UPB_DEFTYPE_MASK) == 0);
275
+ UPB_ASSERT((sizeof(upb_ServiceDef) & UPB_DEFTYPE_MASK) == 0);
276
+ UPB_ASSERT((sizeof(upb_OneofDef) & UPB_DEFTYPE_MASK) == 0);
277
+ uintptr_t num = (uintptr_t)ptr;
278
+ UPB_ASSERT((num & UPB_DEFTYPE_MASK) == 0);
279
+ num |= type;
280
+ return upb_value_constptr((const void*)num);
281
+ }
282
+
283
+ /* isalpha() etc. from <ctype.h> are locale-dependent, which we don't want. */
284
+ static bool upb_isbetween(uint8_t c, uint8_t low, uint8_t high) {
285
+ return c >= low && c <= high;
286
+ }
287
+
288
+ static char upb_ascii_lower(char ch) {
289
+ // Per ASCII this will lower-case a letter. If the result is a letter, the
290
+ // input was definitely a letter. If the output is not a letter, this may
291
+ // have transformed the character unpredictably.
292
+ return ch | 0x20;
293
+ }
294
+
295
+ static bool upb_isletter(char c) {
296
+ char lower = upb_ascii_lower(c);
297
+ return upb_isbetween(lower, 'a', 'z') || c == '_';
298
+ }
299
+
300
+ static bool upb_isalphanum(char c) {
301
+ return upb_isletter(c) || upb_isbetween(c, '0', '9');
302
+ }
303
+
304
+ static const char* shortdefname(const char* fullname) {
305
+ const char* p;
306
+
307
+ if (fullname == NULL) {
308
+ return NULL;
309
+ } else if ((p = strrchr(fullname, '.')) == NULL) {
310
+ /* No '.' in the name, return the full string. */
311
+ return fullname;
312
+ } else {
313
+ /* Return one past the last '.'. */
314
+ return p + 1;
315
+ }
316
+ }
317
+
318
+ /* All submessage fields are lower than all other fields.
319
+ * Secondly, fields are increasing in order. */
320
+ uint32_t field_rank(const upb_FieldDef* f) {
321
+ uint32_t ret = upb_FieldDef_Number(f);
322
+ const uint32_t high_bit = 1 << 30;
323
+ UPB_ASSERT(ret < high_bit);
324
+ if (!upb_FieldDef_IsSubMessage(f)) ret |= high_bit;
325
+ return ret;
326
+ }
327
+
328
+ int cmp_fields(const void* p1, const void* p2) {
329
+ const upb_FieldDef* f1 = *(upb_FieldDef* const*)p1;
330
+ const upb_FieldDef* f2 = *(upb_FieldDef* const*)p2;
331
+ return field_rank(f1) - field_rank(f2);
332
+ }
333
+
334
+ static void upb_Status_setoom(upb_Status* status) {
335
+ upb_Status_SetErrorMessage(status, "out of memory");
336
+ }
337
+
338
+ static void assign_msg_wellknowntype(upb_MessageDef* m) {
339
+ const char* name = upb_MessageDef_FullName(m);
340
+ if (name == NULL) {
341
+ m->well_known_type = kUpb_WellKnown_Unspecified;
342
+ return;
343
+ }
344
+ if (!strcmp(name, "google.protobuf.Any")) {
345
+ m->well_known_type = kUpb_WellKnown_Any;
346
+ } else if (!strcmp(name, "google.protobuf.FieldMask")) {
347
+ m->well_known_type = kUpb_WellKnown_FieldMask;
348
+ } else if (!strcmp(name, "google.protobuf.Duration")) {
349
+ m->well_known_type = kUpb_WellKnown_Duration;
350
+ } else if (!strcmp(name, "google.protobuf.Timestamp")) {
351
+ m->well_known_type = kUpb_WellKnown_Timestamp;
352
+ } else if (!strcmp(name, "google.protobuf.DoubleValue")) {
353
+ m->well_known_type = kUpb_WellKnown_DoubleValue;
354
+ } else if (!strcmp(name, "google.protobuf.FloatValue")) {
355
+ m->well_known_type = kUpb_WellKnown_FloatValue;
356
+ } else if (!strcmp(name, "google.protobuf.Int64Value")) {
357
+ m->well_known_type = kUpb_WellKnown_Int64Value;
358
+ } else if (!strcmp(name, "google.protobuf.UInt64Value")) {
359
+ m->well_known_type = kUpb_WellKnown_UInt64Value;
360
+ } else if (!strcmp(name, "google.protobuf.Int32Value")) {
361
+ m->well_known_type = kUpb_WellKnown_Int32Value;
362
+ } else if (!strcmp(name, "google.protobuf.UInt32Value")) {
363
+ m->well_known_type = kUpb_WellKnown_UInt32Value;
364
+ } else if (!strcmp(name, "google.protobuf.BoolValue")) {
365
+ m->well_known_type = kUpb_WellKnown_BoolValue;
366
+ } else if (!strcmp(name, "google.protobuf.StringValue")) {
367
+ m->well_known_type = kUpb_WellKnown_StringValue;
368
+ } else if (!strcmp(name, "google.protobuf.BytesValue")) {
369
+ m->well_known_type = kUpb_WellKnown_BytesValue;
370
+ } else if (!strcmp(name, "google.protobuf.Value")) {
371
+ m->well_known_type = kUpb_WellKnown_Value;
372
+ } else if (!strcmp(name, "google.protobuf.ListValue")) {
373
+ m->well_known_type = kUpb_WellKnown_ListValue;
374
+ } else if (!strcmp(name, "google.protobuf.Struct")) {
375
+ m->well_known_type = kUpb_WellKnown_Struct;
376
+ } else {
377
+ m->well_known_type = kUpb_WellKnown_Unspecified;
378
+ }
379
+ }
380
+
381
+ /* upb_EnumDef ****************************************************************/
382
+
383
+ const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e) {
384
+ return e->opts;
385
+ }
386
+
387
+ bool upb_EnumDef_HasOptions(const upb_EnumDef* e) {
388
+ return e->opts != (void*)opt_default;
389
+ }
390
+
391
+ const char* upb_EnumDef_FullName(const upb_EnumDef* e) { return e->full_name; }
392
+
393
+ const char* upb_EnumDef_Name(const upb_EnumDef* e) {
394
+ return shortdefname(e->full_name);
395
+ }
396
+
397
+ const upb_FileDef* upb_EnumDef_File(const upb_EnumDef* e) { return e->file; }
398
+
399
+ const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e) {
400
+ return e->containing_type;
401
+ }
402
+
403
+ int32_t upb_EnumDef_Default(const upb_EnumDef* e) {
404
+ UPB_ASSERT(upb_EnumDef_FindValueByNumber(e, e->defaultval));
405
+ return e->defaultval;
406
+ }
407
+
408
+ int upb_EnumDef_ValueCount(const upb_EnumDef* e) { return e->value_count; }
409
+
410
+ const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize(
411
+ const upb_EnumDef* def, const char* name, size_t len) {
412
+ upb_value v;
413
+ return upb_strtable_lookup2(&def->ntoi, name, len, &v)
414
+ ? upb_value_getconstptr(v)
415
+ : NULL;
416
+ }
417
+
418
+ const upb_EnumValueDef* upb_EnumDef_FindValueByNumber(const upb_EnumDef* def,
419
+ int32_t num) {
420
+ upb_value v;
421
+ return upb_inttable_lookup(&def->iton, num, &v) ? upb_value_getconstptr(v)
422
+ : NULL;
423
+ }
424
+
425
+ bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num) {
426
+ // We could use upb_EnumDef_FindValueByNumber(e, num) != NULL, but we expect
427
+ // this to be faster (especially for small numbers).
428
+ return upb_MiniTable_Enum_CheckValue(e->layout, num);
429
+ }
430
+
431
+ const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i) {
432
+ UPB_ASSERT(0 <= i && i < e->value_count);
433
+ return &e->values[i];
434
+ }
435
+
436
+ /* upb_EnumValueDef ***********************************************************/
437
+
438
+ const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options(
439
+ const upb_EnumValueDef* e) {
440
+ return e->opts;
441
+ }
442
+
443
+ bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* e) {
444
+ return e->opts != (void*)opt_default;
445
+ }
446
+
447
+ const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* ev) {
448
+ return ev->parent;
449
+ }
450
+
451
+ const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* ev) {
452
+ return ev->full_name;
453
+ }
454
+
455
+ const char* upb_EnumValueDef_Name(const upb_EnumValueDef* ev) {
456
+ return shortdefname(ev->full_name);
457
+ }
458
+
459
+ int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* ev) {
460
+ return ev->number;
461
+ }
462
+
463
+ uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* ev) {
464
+ // Compute index in our parent's array.
465
+ return ev - ev->parent->values;
466
+ }
467
+
468
+ /* upb_ExtensionRange
469
+ * ***************************************************************/
470
+
471
+ const google_protobuf_ExtensionRangeOptions* upb_ExtensionRange_Options(
472
+ const upb_ExtensionRange* r) {
473
+ return r->opts;
474
+ }
475
+
476
+ bool upb_ExtensionRange_HasOptions(const upb_ExtensionRange* r) {
477
+ return r->opts != (void*)opt_default;
478
+ }
479
+
480
+ int32_t upb_ExtensionRange_Start(const upb_ExtensionRange* e) {
481
+ return e->start;
482
+ }
483
+
484
+ int32_t upb_ExtensionRange_End(const upb_ExtensionRange* e) { return e->end; }
485
+
486
+ /* upb_FieldDef ***************************************************************/
487
+
488
+ const google_protobuf_FieldOptions* upb_FieldDef_Options(
489
+ const upb_FieldDef* f) {
490
+ return f->opts;
491
+ }
492
+
493
+ bool upb_FieldDef_HasOptions(const upb_FieldDef* f) {
494
+ return f->opts != (void*)opt_default;
495
+ }
496
+
497
+ const char* upb_FieldDef_FullName(const upb_FieldDef* f) {
498
+ return f->full_name;
499
+ }
500
+
501
+ upb_CType upb_FieldDef_CType(const upb_FieldDef* f) {
502
+ switch (f->type_) {
503
+ case kUpb_FieldType_Double:
504
+ return kUpb_CType_Double;
505
+ case kUpb_FieldType_Float:
506
+ return kUpb_CType_Float;
507
+ case kUpb_FieldType_Int64:
508
+ case kUpb_FieldType_SInt64:
509
+ case kUpb_FieldType_SFixed64:
510
+ return kUpb_CType_Int64;
511
+ case kUpb_FieldType_Int32:
512
+ case kUpb_FieldType_SFixed32:
513
+ case kUpb_FieldType_SInt32:
514
+ return kUpb_CType_Int32;
515
+ case kUpb_FieldType_UInt64:
516
+ case kUpb_FieldType_Fixed64:
517
+ return kUpb_CType_UInt64;
518
+ case kUpb_FieldType_UInt32:
519
+ case kUpb_FieldType_Fixed32:
520
+ return kUpb_CType_UInt32;
521
+ case kUpb_FieldType_Enum:
522
+ return kUpb_CType_Enum;
523
+ case kUpb_FieldType_Bool:
524
+ return kUpb_CType_Bool;
525
+ case kUpb_FieldType_String:
526
+ return kUpb_CType_String;
527
+ case kUpb_FieldType_Bytes:
528
+ return kUpb_CType_Bytes;
529
+ case kUpb_FieldType_Group:
530
+ case kUpb_FieldType_Message:
531
+ return kUpb_CType_Message;
532
+ }
533
+ UPB_UNREACHABLE();
534
+ }
535
+
536
+ upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f) { return f->type_; }
537
+
538
+ uint32_t upb_FieldDef_Index(const upb_FieldDef* f) { return f->index_; }
539
+
540
+ upb_Label upb_FieldDef_Label(const upb_FieldDef* f) { return f->label_; }
541
+
542
+ uint32_t upb_FieldDef_Number(const upb_FieldDef* f) { return f->number_; }
543
+
544
+ bool upb_FieldDef_IsExtension(const upb_FieldDef* f) {
545
+ return f->is_extension_;
546
+ }
547
+
548
+ bool upb_FieldDef_IsPacked(const upb_FieldDef* f) { return f->packed_; }
549
+
550
+ const char* upb_FieldDef_Name(const upb_FieldDef* f) {
551
+ return shortdefname(f->full_name);
552
+ }
553
+
554
+ const char* upb_FieldDef_JsonName(const upb_FieldDef* f) {
555
+ return f->json_name;
556
+ }
557
+
558
+ bool upb_FieldDef_HasJsonName(const upb_FieldDef* f) {
559
+ return f->has_json_name_;
560
+ }
561
+
562
+ const upb_FileDef* upb_FieldDef_File(const upb_FieldDef* f) { return f->file; }
563
+
564
+ const upb_MessageDef* upb_FieldDef_ContainingType(const upb_FieldDef* f) {
565
+ return f->msgdef;
566
+ }
567
+
568
+ const upb_MessageDef* upb_FieldDef_ExtensionScope(const upb_FieldDef* f) {
569
+ return f->is_extension_ ? f->scope.extension_scope : NULL;
570
+ }
571
+
572
+ const upb_OneofDef* upb_FieldDef_ContainingOneof(const upb_FieldDef* f) {
573
+ return f->is_extension_ ? NULL : f->scope.oneof;
574
+ }
575
+
576
+ const upb_OneofDef* upb_FieldDef_RealContainingOneof(const upb_FieldDef* f) {
577
+ const upb_OneofDef* oneof = upb_FieldDef_ContainingOneof(f);
578
+ if (!oneof || upb_OneofDef_IsSynthetic(oneof)) return NULL;
579
+ return oneof;
580
+ }
581
+
582
+ upb_MessageValue upb_FieldDef_Default(const upb_FieldDef* f) {
583
+ UPB_ASSERT(!upb_FieldDef_IsSubMessage(f));
584
+ upb_MessageValue ret;
585
+
586
+ switch (upb_FieldDef_CType(f)) {
587
+ case kUpb_CType_Bool:
588
+ return (upb_MessageValue){.bool_val = f->defaultval.boolean};
589
+ case kUpb_CType_Int64:
590
+ return (upb_MessageValue){.int64_val = f->defaultval.sint};
591
+ case kUpb_CType_UInt64:
592
+ return (upb_MessageValue){.uint64_val = f->defaultval.uint};
593
+ case kUpb_CType_Enum:
594
+ case kUpb_CType_Int32:
595
+ return (upb_MessageValue){.int32_val = (int32_t)f->defaultval.sint};
596
+ case kUpb_CType_UInt32:
597
+ return (upb_MessageValue){.uint32_val = (uint32_t)f->defaultval.uint};
598
+ case kUpb_CType_Float:
599
+ return (upb_MessageValue){.float_val = f->defaultval.flt};
600
+ case kUpb_CType_Double:
601
+ return (upb_MessageValue){.double_val = f->defaultval.dbl};
602
+ case kUpb_CType_String:
603
+ case kUpb_CType_Bytes: {
604
+ str_t* str = f->defaultval.str;
605
+ if (str) {
606
+ return (upb_MessageValue){
607
+ .str_val = (upb_StringView){.data = str->str, .size = str->len}};
608
+ } else {
609
+ return (upb_MessageValue){
610
+ .str_val = (upb_StringView){.data = NULL, .size = 0}};
611
+ }
612
+ }
613
+ default:
614
+ UPB_UNREACHABLE();
615
+ }
616
+
617
+ return ret;
618
+ }
619
+
620
+ const upb_MessageDef* upb_FieldDef_MessageSubDef(const upb_FieldDef* f) {
621
+ return upb_FieldDef_CType(f) == kUpb_CType_Message ? f->sub.msgdef : NULL;
622
+ }
623
+
624
+ const upb_EnumDef* upb_FieldDef_EnumSubDef(const upb_FieldDef* f) {
625
+ return upb_FieldDef_CType(f) == kUpb_CType_Enum ? f->sub.enumdef : NULL;
626
+ }
627
+
628
+ const upb_MiniTable_Field* upb_FieldDef_MiniTable(const upb_FieldDef* f) {
629
+ UPB_ASSERT(!upb_FieldDef_IsExtension(f));
630
+ return &f->msgdef->layout->fields[f->layout_index];
631
+ }
632
+
633
+ const upb_MiniTable_Extension* _upb_FieldDef_ExtensionMiniTable(
634
+ const upb_FieldDef* f) {
635
+ UPB_ASSERT(upb_FieldDef_IsExtension(f));
636
+ return f->file->ext_layouts[f->layout_index];
637
+ }
638
+
639
+ bool _upb_FieldDef_IsProto3Optional(const upb_FieldDef* f) {
640
+ return f->proto3_optional_;
641
+ }
642
+
643
+ bool upb_FieldDef_IsSubMessage(const upb_FieldDef* f) {
644
+ return upb_FieldDef_CType(f) == kUpb_CType_Message;
645
+ }
646
+
647
+ bool upb_FieldDef_IsString(const upb_FieldDef* f) {
648
+ return upb_FieldDef_CType(f) == kUpb_CType_String ||
649
+ upb_FieldDef_CType(f) == kUpb_CType_Bytes;
650
+ }
651
+
652
+ bool upb_FieldDef_IsRepeated(const upb_FieldDef* f) {
653
+ return upb_FieldDef_Label(f) == kUpb_Label_Repeated;
654
+ }
655
+
656
+ bool upb_FieldDef_IsPrimitive(const upb_FieldDef* f) {
657
+ return !upb_FieldDef_IsString(f) && !upb_FieldDef_IsSubMessage(f);
658
+ }
659
+
660
+ bool upb_FieldDef_IsMap(const upb_FieldDef* f) {
661
+ return upb_FieldDef_IsRepeated(f) && upb_FieldDef_IsSubMessage(f) &&
662
+ upb_MessageDef_IsMapEntry(upb_FieldDef_MessageSubDef(f));
663
+ }
664
+
665
+ bool upb_FieldDef_HasDefault(const upb_FieldDef* f) { return f->has_default; }
666
+
667
+ bool upb_FieldDef_HasSubDef(const upb_FieldDef* f) {
668
+ return upb_FieldDef_IsSubMessage(f) ||
669
+ upb_FieldDef_CType(f) == kUpb_CType_Enum;
670
+ }
671
+
672
+ bool upb_FieldDef_HasPresence(const upb_FieldDef* f) {
673
+ if (upb_FieldDef_IsRepeated(f)) return false;
674
+ return upb_FieldDef_IsSubMessage(f) || upb_FieldDef_ContainingOneof(f) ||
675
+ f->file->syntax == kUpb_Syntax_Proto2;
676
+ }
677
+
678
+ static bool between(int32_t x, int32_t low, int32_t high) {
679
+ return x >= low && x <= high;
680
+ }
681
+
682
+ bool upb_FieldDef_checklabel(int32_t label) { return between(label, 1, 3); }
683
+ bool upb_FieldDef_checktype(int32_t type) { return between(type, 1, 11); }
684
+ bool upb_FieldDef_checkintfmt(int32_t fmt) { return between(fmt, 1, 3); }
685
+
686
+ bool upb_FieldDef_checkdescriptortype(int32_t type) {
687
+ return between(type, 1, 18);
688
+ }
689
+
690
+ /* upb_MessageDef
691
+ * *****************************************************************/
692
+
693
+ const google_protobuf_MessageOptions* upb_MessageDef_Options(
694
+ const upb_MessageDef* m) {
695
+ return m->opts;
696
+ }
697
+
698
+ bool upb_MessageDef_HasOptions(const upb_MessageDef* m) {
699
+ return m->opts != (void*)opt_default;
700
+ }
701
+
702
+ const char* upb_MessageDef_FullName(const upb_MessageDef* m) {
703
+ return m->full_name;
704
+ }
705
+
706
+ const upb_FileDef* upb_MessageDef_File(const upb_MessageDef* m) {
707
+ return m->file;
708
+ }
709
+
710
+ const upb_MessageDef* upb_MessageDef_ContainingType(const upb_MessageDef* m) {
711
+ return m->containing_type;
712
+ }
713
+
714
+ const char* upb_MessageDef_Name(const upb_MessageDef* m) {
715
+ return shortdefname(m->full_name);
716
+ }
717
+
718
+ upb_Syntax upb_MessageDef_Syntax(const upb_MessageDef* m) {
719
+ return m->file->syntax;
720
+ }
721
+
722
+ const upb_FieldDef* upb_MessageDef_FindFieldByNumber(const upb_MessageDef* m,
723
+ uint32_t i) {
724
+ upb_value val;
725
+ return upb_inttable_lookup(&m->itof, i, &val) ? upb_value_getconstptr(val)
726
+ : NULL;
727
+ }
728
+
729
+ const upb_FieldDef* upb_MessageDef_FindFieldByNameWithSize(
730
+ const upb_MessageDef* m, const char* name, size_t len) {
731
+ upb_value val;
732
+
733
+ if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
734
+ return NULL;
735
+ }
736
+
737
+ return unpack_def(val, UPB_DEFTYPE_FIELD);
738
+ }
739
+
740
+ const upb_OneofDef* upb_MessageDef_FindOneofByNameWithSize(
741
+ const upb_MessageDef* m, const char* name, size_t len) {
742
+ upb_value val;
743
+
744
+ if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
745
+ return NULL;
746
+ }
747
+
748
+ return unpack_def(val, UPB_DEFTYPE_ONEOF);
749
+ }
750
+
751
+ bool upb_MessageDef_FindByNameWithSize(const upb_MessageDef* m,
752
+ const char* name, size_t len,
753
+ const upb_FieldDef** out_f,
754
+ const upb_OneofDef** out_o) {
755
+ upb_value val;
756
+
757
+ if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
758
+ return false;
759
+ }
760
+
761
+ const upb_FieldDef* f = unpack_def(val, UPB_DEFTYPE_FIELD);
762
+ const upb_OneofDef* o = unpack_def(val, UPB_DEFTYPE_ONEOF);
763
+ if (out_f) *out_f = f;
764
+ if (out_o) *out_o = o;
765
+ return f || o; /* False if this was a JSON name. */
766
+ }
767
+
768
+ const upb_FieldDef* upb_MessageDef_FindByJsonNameWithSize(
769
+ const upb_MessageDef* m, const char* name, size_t len) {
770
+ upb_value val;
771
+ const upb_FieldDef* f;
772
+
773
+ if (!upb_strtable_lookup2(&m->ntof, name, len, &val)) {
774
+ return NULL;
775
+ }
776
+
777
+ f = unpack_def(val, UPB_DEFTYPE_FIELD);
778
+ if (!f) f = unpack_def(val, UPB_DEFTYPE_FIELD_JSONNAME);
779
+
780
+ return f;
781
+ }
782
+
783
+ int upb_MessageDef_numfields(const upb_MessageDef* m) { return m->field_count; }
784
+
785
+ int upb_MessageDef_numoneofs(const upb_MessageDef* m) { return m->oneof_count; }
786
+
787
+ int upb_MessageDef_numrealoneofs(const upb_MessageDef* m) {
788
+ return m->real_oneof_count;
789
+ }
790
+
791
+ int upb_MessageDef_ExtensionRangeCount(const upb_MessageDef* m) {
792
+ return m->ext_range_count;
793
+ }
794
+
795
+ int upb_MessageDef_FieldCount(const upb_MessageDef* m) {
796
+ return m->field_count;
797
+ }
798
+
799
+ int upb_MessageDef_OneofCount(const upb_MessageDef* m) {
800
+ return m->oneof_count;
801
+ }
802
+
803
+ int upb_MessageDef_NestedMessageCount(const upb_MessageDef* m) {
804
+ return m->nested_msg_count;
805
+ }
806
+
807
+ int upb_MessageDef_NestedEnumCount(const upb_MessageDef* m) {
808
+ return m->nested_enum_count;
809
+ }
810
+
811
+ int upb_MessageDef_NestedExtensionCount(const upb_MessageDef* m) {
812
+ return m->nested_ext_count;
813
+ }
814
+
815
+ int upb_MessageDef_realoneofcount(const upb_MessageDef* m) {
816
+ return m->real_oneof_count;
817
+ }
818
+
819
+ const upb_MiniTable* upb_MessageDef_MiniTable(const upb_MessageDef* m) {
820
+ return m->layout;
821
+ }
822
+
823
+ const upb_ExtensionRange* upb_MessageDef_ExtensionRange(const upb_MessageDef* m,
824
+ int i) {
825
+ UPB_ASSERT(0 <= i && i < m->ext_range_count);
826
+ return &m->ext_ranges[i];
827
+ }
828
+
829
+ const upb_FieldDef* upb_MessageDef_Field(const upb_MessageDef* m, int i) {
830
+ UPB_ASSERT(0 <= i && i < m->field_count);
831
+ return &m->fields[i];
832
+ }
833
+
834
+ const upb_OneofDef* upb_MessageDef_Oneof(const upb_MessageDef* m, int i) {
835
+ UPB_ASSERT(0 <= i && i < m->oneof_count);
836
+ return &m->oneofs[i];
837
+ }
838
+
839
+ const upb_MessageDef* upb_MessageDef_NestedMessage(const upb_MessageDef* m,
840
+ int i) {
841
+ UPB_ASSERT(0 <= i && i < m->nested_msg_count);
842
+ return &m->nested_msgs[i];
843
+ }
844
+
845
+ const upb_EnumDef* upb_MessageDef_NestedEnum(const upb_MessageDef* m, int i) {
846
+ UPB_ASSERT(0 <= i && i < m->nested_enum_count);
847
+ return &m->nested_enums[i];
848
+ }
849
+
850
+ const upb_FieldDef* upb_MessageDef_NestedExtension(const upb_MessageDef* m,
851
+ int i) {
852
+ UPB_ASSERT(0 <= i && i < m->nested_ext_count);
853
+ return &m->nested_exts[i];
854
+ }
855
+
856
+ upb_WellKnown upb_MessageDef_WellKnownType(const upb_MessageDef* m) {
857
+ return m->well_known_type;
858
+ }
859
+
860
+ /* upb_OneofDef ***************************************************************/
861
+
862
+ const google_protobuf_OneofOptions* upb_OneofDef_Options(
863
+ const upb_OneofDef* o) {
864
+ return o->opts;
865
+ }
866
+
867
+ bool upb_OneofDef_HasOptions(const upb_OneofDef* o) {
868
+ return o->opts != (void*)opt_default;
869
+ }
870
+
871
+ const char* upb_OneofDef_Name(const upb_OneofDef* o) {
872
+ return shortdefname(o->full_name);
873
+ }
874
+
875
+ const upb_MessageDef* upb_OneofDef_ContainingType(const upb_OneofDef* o) {
876
+ return o->parent;
877
+ }
878
+
879
+ int upb_OneofDef_FieldCount(const upb_OneofDef* o) { return o->field_count; }
880
+
881
+ const upb_FieldDef* upb_OneofDef_Field(const upb_OneofDef* o, int i) {
882
+ UPB_ASSERT(i < o->field_count);
883
+ return o->fields[i];
884
+ }
885
+
886
+ int upb_OneofDef_numfields(const upb_OneofDef* o) { return o->field_count; }
887
+
888
+ uint32_t upb_OneofDef_Index(const upb_OneofDef* o) {
889
+ // Compute index in our parent's array.
890
+ return o - o->parent->oneofs;
891
+ }
892
+
893
+ bool upb_OneofDef_IsSynthetic(const upb_OneofDef* o) { return o->synthetic; }
894
+
895
+ const upb_FieldDef* upb_OneofDef_LookupNameWithSize(const upb_OneofDef* o,
896
+ const char* name,
897
+ size_t length) {
898
+ upb_value val;
899
+ return upb_strtable_lookup2(&o->ntof, name, length, &val)
900
+ ? upb_value_getptr(val)
901
+ : NULL;
902
+ }
903
+
904
+ const upb_FieldDef* upb_OneofDef_LookupNumber(const upb_OneofDef* o,
905
+ uint32_t num) {
906
+ upb_value val;
907
+ return upb_inttable_lookup(&o->itof, num, &val) ? upb_value_getptr(val)
908
+ : NULL;
909
+ }
910
+
911
+ /* upb_FileDef ****************************************************************/
912
+
913
+ const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f) {
914
+ return f->opts;
915
+ }
916
+
917
+ bool upb_FileDef_HasOptions(const upb_FileDef* f) {
918
+ return f->opts != (void*)opt_default;
919
+ }
920
+
921
+ const char* upb_FileDef_Name(const upb_FileDef* f) { return f->name; }
922
+
923
+ const char* upb_FileDef_Package(const upb_FileDef* f) { return f->package; }
924
+
925
+ upb_Syntax upb_FileDef_Syntax(const upb_FileDef* f) { return f->syntax; }
926
+
927
+ int upb_FileDef_TopLevelMessageCount(const upb_FileDef* f) {
928
+ return f->top_lvl_msg_count;
929
+ }
930
+
931
+ int upb_FileDef_DependencyCount(const upb_FileDef* f) { return f->dep_count; }
932
+
933
+ int upb_FileDef_PublicDependencyCount(const upb_FileDef* f) {
934
+ return f->public_dep_count;
935
+ }
936
+
937
+ int upb_FileDef_WeakDependencyCount(const upb_FileDef* f) {
938
+ return f->weak_dep_count;
939
+ }
940
+
941
+ const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f) {
942
+ return f->public_deps;
943
+ }
944
+
945
+ const int32_t* _upb_FileDef_WeakDependencyIndexes(const upb_FileDef* f) {
946
+ return f->weak_deps;
947
+ }
948
+
949
+ int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f) {
950
+ return f->top_lvl_enum_count;
951
+ }
952
+
953
+ int upb_FileDef_TopLevelExtensionCount(const upb_FileDef* f) {
954
+ return f->top_lvl_ext_count;
955
+ }
956
+
957
+ int upb_FileDef_ServiceCount(const upb_FileDef* f) { return f->service_count; }
958
+
959
+ const upb_FileDef* upb_FileDef_Dependency(const upb_FileDef* f, int i) {
960
+ UPB_ASSERT(0 <= i && i < f->dep_count);
961
+ return f->deps[i];
962
+ }
963
+
964
+ const upb_FileDef* upb_FileDef_PublicDependency(const upb_FileDef* f, int i) {
965
+ UPB_ASSERT(0 <= i && i < f->public_dep_count);
966
+ return f->deps[f->public_deps[i]];
967
+ }
968
+
969
+ const upb_FileDef* upb_FileDef_WeakDependency(const upb_FileDef* f, int i) {
970
+ UPB_ASSERT(0 <= i && i < f->public_dep_count);
971
+ return f->deps[f->weak_deps[i]];
972
+ }
973
+
974
+ const upb_MessageDef* upb_FileDef_TopLevelMessage(const upb_FileDef* f, int i) {
975
+ UPB_ASSERT(0 <= i && i < f->top_lvl_msg_count);
976
+ return &f->top_lvl_msgs[i];
977
+ }
978
+
979
+ const upb_EnumDef* upb_FileDef_TopLevelEnum(const upb_FileDef* f, int i) {
980
+ UPB_ASSERT(0 <= i && i < f->top_lvl_enum_count);
981
+ return &f->top_lvl_enums[i];
982
+ }
983
+
984
+ const upb_FieldDef* upb_FileDef_TopLevelExtension(const upb_FileDef* f, int i) {
985
+ UPB_ASSERT(0 <= i && i < f->top_lvl_ext_count);
986
+ return &f->top_lvl_exts[i];
987
+ }
988
+
989
+ const upb_ServiceDef* upb_FileDef_Service(const upb_FileDef* f, int i) {
990
+ UPB_ASSERT(0 <= i && i < f->service_count);
991
+ return &f->services[i];
992
+ }
993
+
994
+ const upb_DefPool* upb_FileDef_Pool(const upb_FileDef* f) { return f->symtab; }
995
+
996
+ /* upb_MethodDef **************************************************************/
997
+
998
+ const google_protobuf_MethodOptions* upb_MethodDef_Options(
999
+ const upb_MethodDef* m) {
1000
+ return m->opts;
1001
+ }
1002
+
1003
+ bool upb_MethodDef_HasOptions(const upb_MethodDef* m) {
1004
+ return m->opts != (void*)opt_default;
1005
+ }
1006
+
1007
+ const char* upb_MethodDef_FullName(const upb_MethodDef* m) {
1008
+ return m->full_name;
1009
+ }
1010
+
1011
+ int upb_MethodDef_Index(const upb_MethodDef* m) { return m->index; }
1012
+
1013
+ const char* upb_MethodDef_Name(const upb_MethodDef* m) {
1014
+ return shortdefname(m->full_name);
1015
+ }
1016
+
1017
+ const upb_ServiceDef* upb_MethodDef_Service(const upb_MethodDef* m) {
1018
+ return m->service;
1019
+ }
1020
+
1021
+ const upb_MessageDef* upb_MethodDef_InputType(const upb_MethodDef* m) {
1022
+ return m->input_type;
1023
+ }
1024
+
1025
+ const upb_MessageDef* upb_MethodDef_OutputType(const upb_MethodDef* m) {
1026
+ return m->output_type;
1027
+ }
1028
+
1029
+ bool upb_MethodDef_ClientStreaming(const upb_MethodDef* m) {
1030
+ return m->client_streaming;
1031
+ }
1032
+
1033
+ bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m) {
1034
+ return m->server_streaming;
1035
+ }
1036
+
1037
+ /* upb_ServiceDef *************************************************************/
1038
+
1039
+ const google_protobuf_ServiceOptions* upb_ServiceDef_Options(
1040
+ const upb_ServiceDef* s) {
1041
+ return s->opts;
1042
+ }
1043
+
1044
+ bool upb_ServiceDef_HasOptions(const upb_ServiceDef* s) {
1045
+ return s->opts != (void*)opt_default;
1046
+ }
1047
+
1048
+ const char* upb_ServiceDef_FullName(const upb_ServiceDef* s) {
1049
+ return s->full_name;
1050
+ }
1051
+
1052
+ const char* upb_ServiceDef_Name(const upb_ServiceDef* s) {
1053
+ return shortdefname(s->full_name);
1054
+ }
1055
+
1056
+ int upb_ServiceDef_Index(const upb_ServiceDef* s) { return s->index; }
1057
+
1058
+ const upb_FileDef* upb_ServiceDef_File(const upb_ServiceDef* s) {
1059
+ return s->file;
1060
+ }
1061
+
1062
+ int upb_ServiceDef_MethodCount(const upb_ServiceDef* s) {
1063
+ return s->method_count;
1064
+ }
1065
+
1066
+ const upb_MethodDef* upb_ServiceDef_Method(const upb_ServiceDef* s, int i) {
1067
+ return i < 0 || i >= s->method_count ? NULL : &s->methods[i];
1068
+ }
1069
+
1070
+ const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s,
1071
+ const char* name) {
1072
+ for (int i = 0; i < s->method_count; i++) {
1073
+ if (strcmp(name, upb_MethodDef_Name(&s->methods[i])) == 0) {
1074
+ return &s->methods[i];
1075
+ }
1076
+ }
1077
+ return NULL;
1078
+ }
1079
+
1080
+ /* upb_DefPool ****************************************************************/
1081
+
1082
+ void upb_DefPool_Free(upb_DefPool* s) {
1083
+ upb_Arena_Free(s->arena);
1084
+ upb_gfree(s);
1085
+ }
1086
+
1087
+ upb_DefPool* upb_DefPool_New(void) {
1088
+ upb_DefPool* s = upb_gmalloc(sizeof(*s));
1089
+
1090
+ if (!s) {
1091
+ return NULL;
1092
+ }
1093
+
1094
+ s->arena = upb_Arena_New();
1095
+ s->bytes_loaded = 0;
1096
+
1097
+ if (!upb_strtable_init(&s->syms, 32, s->arena) ||
1098
+ !upb_strtable_init(&s->files, 4, s->arena) ||
1099
+ !upb_inttable_init(&s->exts, s->arena)) {
1100
+ goto err;
1101
+ }
1102
+
1103
+ s->extreg = upb_ExtensionRegistry_New(s->arena);
1104
+ if (!s->extreg) goto err;
1105
+ return s;
1106
+
1107
+ err:
1108
+ upb_Arena_Free(s->arena);
1109
+ upb_gfree(s);
1110
+ return NULL;
1111
+ }
1112
+
1113
+ static const void* symtab_lookup(const upb_DefPool* s, const char* sym,
1114
+ upb_deftype_t type) {
1115
+ upb_value v;
1116
+ return upb_strtable_lookup(&s->syms, sym, &v) ? unpack_def(v, type) : NULL;
1117
+ }
1118
+
1119
+ static const void* symtab_lookup2(const upb_DefPool* s, const char* sym,
1120
+ size_t size, upb_deftype_t type) {
1121
+ upb_value v;
1122
+ return upb_strtable_lookup2(&s->syms, sym, size, &v) ? unpack_def(v, type)
1123
+ : NULL;
1124
+ }
1125
+
1126
+ const upb_MessageDef* upb_DefPool_FindMessageByName(const upb_DefPool* s,
1127
+ const char* sym) {
1128
+ return symtab_lookup(s, sym, UPB_DEFTYPE_MSG);
1129
+ }
1130
+
1131
+ const upb_MessageDef* upb_DefPool_FindMessageByNameWithSize(
1132
+ const upb_DefPool* s, const char* sym, size_t len) {
1133
+ return symtab_lookup2(s, sym, len, UPB_DEFTYPE_MSG);
1134
+ }
1135
+
1136
+ const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s,
1137
+ const char* sym) {
1138
+ return symtab_lookup(s, sym, UPB_DEFTYPE_ENUM);
1139
+ }
1140
+
1141
+ const upb_EnumValueDef* upb_DefPool_FindEnumByNameval(const upb_DefPool* s,
1142
+ const char* sym) {
1143
+ return symtab_lookup(s, sym, UPB_DEFTYPE_ENUMVAL);
1144
+ }
1145
+
1146
+ const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s,
1147
+ const char* name) {
1148
+ upb_value v;
1149
+ return upb_strtable_lookup(&s->files, name, &v)
1150
+ ? unpack_def(v, UPB_DEFTYPE_FILE)
1151
+ : NULL;
1152
+ }
1153
+
1154
+ const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s,
1155
+ const char* name,
1156
+ size_t len) {
1157
+ upb_value v;
1158
+ return upb_strtable_lookup2(&s->files, name, len, &v)
1159
+ ? unpack_def(v, UPB_DEFTYPE_FILE)
1160
+ : NULL;
1161
+ }
1162
+
1163
+ const upb_FieldDef* upb_DefPool_FindExtensionByNameWithSize(
1164
+ const upb_DefPool* s, const char* name, size_t size) {
1165
+ upb_value v;
1166
+ if (!upb_strtable_lookup2(&s->syms, name, size, &v)) return NULL;
1167
+
1168
+ switch (deftype(v)) {
1169
+ case UPB_DEFTYPE_FIELD:
1170
+ return unpack_def(v, UPB_DEFTYPE_FIELD);
1171
+ case UPB_DEFTYPE_MSG: {
1172
+ const upb_MessageDef* m = unpack_def(v, UPB_DEFTYPE_MSG);
1173
+ return m->in_message_set ? &m->nested_exts[0] : NULL;
1174
+ }
1175
+ default:
1176
+ break;
1177
+ }
1178
+
1179
+ return NULL;
1180
+ }
1181
+
1182
+ const upb_FieldDef* upb_DefPool_FindExtensionByName(const upb_DefPool* s,
1183
+ const char* sym) {
1184
+ return upb_DefPool_FindExtensionByNameWithSize(s, sym, strlen(sym));
1185
+ }
1186
+
1187
+ const upb_ServiceDef* upb_DefPool_FindServiceByName(const upb_DefPool* s,
1188
+ const char* name) {
1189
+ return symtab_lookup(s, name, UPB_DEFTYPE_SERVICE);
1190
+ }
1191
+
1192
+ const upb_ServiceDef* upb_DefPool_FindServiceByNameWithSize(
1193
+ const upb_DefPool* s, const char* name, size_t size) {
1194
+ return symtab_lookup2(s, name, size, UPB_DEFTYPE_SERVICE);
1195
+ }
1196
+
1197
+ const upb_FileDef* upb_DefPool_FindFileContainingSymbol(const upb_DefPool* s,
1198
+ const char* name) {
1199
+ upb_value v;
1200
+ // TODO(haberman): non-extension fields and oneofs.
1201
+ if (upb_strtable_lookup(&s->syms, name, &v)) {
1202
+ switch (deftype(v)) {
1203
+ case UPB_DEFTYPE_EXT: {
1204
+ const upb_FieldDef* f = unpack_def(v, UPB_DEFTYPE_EXT);
1205
+ return upb_FieldDef_File(f);
1206
+ }
1207
+ case UPB_DEFTYPE_MSG: {
1208
+ const upb_MessageDef* m = unpack_def(v, UPB_DEFTYPE_MSG);
1209
+ return upb_MessageDef_File(m);
1210
+ }
1211
+ case UPB_DEFTYPE_ENUM: {
1212
+ const upb_EnumDef* e = unpack_def(v, UPB_DEFTYPE_ENUM);
1213
+ return upb_EnumDef_File(e);
1214
+ }
1215
+ case UPB_DEFTYPE_ENUMVAL: {
1216
+ const upb_EnumValueDef* ev = unpack_def(v, UPB_DEFTYPE_ENUMVAL);
1217
+ return upb_EnumDef_File(upb_EnumValueDef_Enum(ev));
1218
+ }
1219
+ case UPB_DEFTYPE_SERVICE: {
1220
+ const upb_ServiceDef* service = unpack_def(v, UPB_DEFTYPE_SERVICE);
1221
+ return upb_ServiceDef_File(service);
1222
+ }
1223
+ default:
1224
+ UPB_UNREACHABLE();
1225
+ }
1226
+ }
1227
+
1228
+ const char* last_dot = strrchr(name, '.');
1229
+ if (last_dot) {
1230
+ const upb_MessageDef* parent =
1231
+ upb_DefPool_FindMessageByNameWithSize(s, name, last_dot - name);
1232
+ if (parent) {
1233
+ const char* shortname = last_dot + 1;
1234
+ if (upb_MessageDef_FindByNameWithSize(parent, shortname,
1235
+ strlen(shortname), NULL, NULL)) {
1236
+ return upb_MessageDef_File(parent);
1237
+ }
1238
+ }
1239
+ }
1240
+
1241
+ return NULL;
1242
+ }
1243
+
1244
+ /* Code to build defs from descriptor protos. *********************************/
1245
+
1246
+ /* There is a question of how much validation to do here. It will be difficult
1247
+ * to perfectly match the amount of validation performed by proto2. But since
1248
+ * this code is used to directly build defs from Ruby (for example) we do need
1249
+ * to validate important constraints like uniqueness of names and numbers. */
1250
+
1251
+ #define CHK_OOM(x) \
1252
+ if (!(x)) { \
1253
+ symtab_oomerr(ctx); \
1254
+ }
1255
+
1256
+ typedef struct {
1257
+ upb_DefPool* symtab;
1258
+ upb_FileDef* file; /* File we are building. */
1259
+ upb_Arena* arena; /* Allocate defs here. */
1260
+ upb_Arena* tmp_arena; /* For temporary allocations. */
1261
+ const upb_MiniTable_File* layout; /* NULL if we should build layouts. */
1262
+ int enum_count; /* Count of enums built so far. */
1263
+ int msg_count; /* Count of messages built so far. */
1264
+ int ext_count; /* Count of extensions built so far. */
1265
+ upb_Status* status; /* Record errors here. */
1266
+ jmp_buf err; /* longjmp() on error. */
1267
+ } symtab_addctx;
1268
+
1269
+ UPB_NORETURN UPB_NOINLINE UPB_PRINTF(2, 3) static void symtab_errf(
1270
+ symtab_addctx* ctx, const char* fmt, ...) {
1271
+ va_list argp;
1272
+ va_start(argp, fmt);
1273
+ upb_Status_VSetErrorFormat(ctx->status, fmt, argp);
1274
+ va_end(argp);
1275
+ UPB_LONGJMP(ctx->err, 1);
1276
+ }
1277
+
1278
+ UPB_NORETURN UPB_NOINLINE static void symtab_oomerr(symtab_addctx* ctx) {
1279
+ upb_Status_setoom(ctx->status);
1280
+ UPB_LONGJMP(ctx->err, 1);
1281
+ }
1282
+
1283
+ void* symtab_alloc(symtab_addctx* ctx, size_t bytes) {
1284
+ if (bytes == 0) return NULL;
1285
+ void* ret = upb_Arena_Malloc(ctx->arena, bytes);
1286
+ if (!ret) symtab_oomerr(ctx);
1287
+ return ret;
1288
+ }
1289
+
1290
+ // We want to copy the options verbatim into the destination options proto.
1291
+ // We use serialize+parse as our deep copy.
1292
+ #define SET_OPTIONS(target, desc_type, options_type, proto) \
1293
+ if (google_protobuf_##desc_type##_has_options(proto)) { \
1294
+ size_t size; \
1295
+ char* pb = google_protobuf_##options_type##_serialize( \
1296
+ google_protobuf_##desc_type##_options(proto), ctx->tmp_arena, &size); \
1297
+ CHK_OOM(pb); \
1298
+ target = google_protobuf_##options_type##_parse(pb, size, ctx->arena); \
1299
+ CHK_OOM(target); \
1300
+ } else { \
1301
+ target = (const google_protobuf_##options_type*)opt_default; \
1302
+ }
1303
+
1304
+ static void check_ident(symtab_addctx* ctx, upb_StringView name, bool full) {
1305
+ const char* str = name.data;
1306
+ size_t len = name.size;
1307
+ bool start = true;
1308
+ size_t i;
1309
+ for (i = 0; i < len; i++) {
1310
+ char c = str[i];
1311
+ if (c == '.') {
1312
+ if (start || !full) {
1313
+ symtab_errf(ctx, "invalid name: unexpected '.' (%.*s)", (int)len, str);
1314
+ }
1315
+ start = true;
1316
+ } else if (start) {
1317
+ if (!upb_isletter(c)) {
1318
+ symtab_errf(
1319
+ ctx,
1320
+ "invalid name: path components must start with a letter (%.*s)",
1321
+ (int)len, str);
1322
+ }
1323
+ start = false;
1324
+ } else {
1325
+ if (!upb_isalphanum(c)) {
1326
+ symtab_errf(ctx, "invalid name: non-alphanumeric character (%.*s)",
1327
+ (int)len, str);
1328
+ }
1329
+ }
1330
+ }
1331
+ if (start) {
1332
+ symtab_errf(ctx, "invalid name: empty part (%.*s)", (int)len, str);
1333
+ }
1334
+ }
1335
+
1336
+ static size_t div_round_up(size_t n, size_t d) { return (n + d - 1) / d; }
1337
+
1338
+ static size_t upb_MessageValue_sizeof(upb_CType type) {
1339
+ switch (type) {
1340
+ case kUpb_CType_Double:
1341
+ case kUpb_CType_Int64:
1342
+ case kUpb_CType_UInt64:
1343
+ return 8;
1344
+ case kUpb_CType_Enum:
1345
+ case kUpb_CType_Int32:
1346
+ case kUpb_CType_UInt32:
1347
+ case kUpb_CType_Float:
1348
+ return 4;
1349
+ case kUpb_CType_Bool:
1350
+ return 1;
1351
+ case kUpb_CType_Message:
1352
+ return sizeof(void*);
1353
+ case kUpb_CType_Bytes:
1354
+ case kUpb_CType_String:
1355
+ return sizeof(upb_StringView);
1356
+ }
1357
+ UPB_UNREACHABLE();
1358
+ }
1359
+
1360
+ static uint8_t upb_msg_fielddefsize(const upb_FieldDef* f) {
1361
+ if (upb_MessageDef_IsMapEntry(upb_FieldDef_ContainingType(f))) {
1362
+ upb_MapEntry ent;
1363
+ UPB_ASSERT(sizeof(ent.k) == sizeof(ent.v));
1364
+ return sizeof(ent.k);
1365
+ } else if (upb_FieldDef_IsRepeated(f)) {
1366
+ return sizeof(void*);
1367
+ } else {
1368
+ return upb_MessageValue_sizeof(upb_FieldDef_CType(f));
1369
+ }
1370
+ }
1371
+
1372
+ static uint32_t upb_MiniTable_place(symtab_addctx* ctx, upb_MiniTable* l,
1373
+ size_t size, const upb_MessageDef* m) {
1374
+ size_t ofs = UPB_ALIGN_UP(l->size, size);
1375
+ size_t next = ofs + size;
1376
+
1377
+ if (next > UINT16_MAX) {
1378
+ symtab_errf(ctx, "size of message %s exceeded max size of %zu bytes",
1379
+ upb_MessageDef_FullName(m), (size_t)UINT16_MAX);
1380
+ }
1381
+
1382
+ l->size = next;
1383
+ return ofs;
1384
+ }
1385
+
1386
+ static int field_number_cmp(const void* p1, const void* p2) {
1387
+ const upb_MiniTable_Field* f1 = p1;
1388
+ const upb_MiniTable_Field* f2 = p2;
1389
+ return f1->number - f2->number;
1390
+ }
1391
+
1392
+ static void assign_layout_indices(const upb_MessageDef* m, upb_MiniTable* l,
1393
+ upb_MiniTable_Field* fields) {
1394
+ int i;
1395
+ int n = upb_MessageDef_numfields(m);
1396
+ int dense_below = 0;
1397
+ for (i = 0; i < n; i++) {
1398
+ upb_FieldDef* f =
1399
+ (upb_FieldDef*)upb_MessageDef_FindFieldByNumber(m, fields[i].number);
1400
+ UPB_ASSERT(f);
1401
+ f->layout_index = i;
1402
+ if (i < UINT8_MAX && fields[i].number == i + 1 &&
1403
+ (i == 0 || fields[i - 1].number == i)) {
1404
+ dense_below = i + 1;
1405
+ }
1406
+ }
1407
+ l->dense_below = dense_below;
1408
+ }
1409
+
1410
+ static uint8_t map_descriptortype(const upb_FieldDef* f) {
1411
+ uint8_t type = upb_FieldDef_Type(f);
1412
+ /* See TableDescriptorType() in upbc/generator.cc for details and
1413
+ * rationale of these exceptions. */
1414
+ if (type == kUpb_FieldType_String && f->file->syntax == kUpb_Syntax_Proto2) {
1415
+ return kUpb_FieldType_Bytes;
1416
+ } else if (type == kUpb_FieldType_Enum &&
1417
+ (f->sub.enumdef->file->syntax == kUpb_Syntax_Proto3 ||
1418
+ UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 ||
1419
+ // TODO(https://github.com/protocolbuffers/upb/issues/541):
1420
+ // fix map enum values to check for unknown enum values and put
1421
+ // them in the unknown field set.
1422
+ upb_MessageDef_IsMapEntry(upb_FieldDef_ContainingType(f)))) {
1423
+ return kUpb_FieldType_Int32;
1424
+ }
1425
+ return type;
1426
+ }
1427
+
1428
+ static void fill_fieldlayout(upb_MiniTable_Field* field,
1429
+ const upb_FieldDef* f) {
1430
+ field->number = upb_FieldDef_Number(f);
1431
+ field->descriptortype = map_descriptortype(f);
1432
+
1433
+ if (upb_FieldDef_IsMap(f)) {
1434
+ field->mode =
1435
+ kUpb_FieldMode_Map | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift);
1436
+ } else if (upb_FieldDef_IsRepeated(f)) {
1437
+ field->mode =
1438
+ kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift);
1439
+ } else {
1440
+ /* Maps descriptor type -> elem_size_lg2. */
1441
+ static const uint8_t sizes[] = {
1442
+ -1, /* invalid descriptor type */
1443
+ kUpb_FieldRep_8Byte, /* DOUBLE */
1444
+ kUpb_FieldRep_4Byte, /* FLOAT */
1445
+ kUpb_FieldRep_8Byte, /* INT64 */
1446
+ kUpb_FieldRep_8Byte, /* UINT64 */
1447
+ kUpb_FieldRep_4Byte, /* INT32 */
1448
+ kUpb_FieldRep_8Byte, /* FIXED64 */
1449
+ kUpb_FieldRep_4Byte, /* FIXED32 */
1450
+ kUpb_FieldRep_1Byte, /* BOOL */
1451
+ kUpb_FieldRep_StringView, /* STRING */
1452
+ kUpb_FieldRep_Pointer, /* GROUP */
1453
+ kUpb_FieldRep_Pointer, /* MESSAGE */
1454
+ kUpb_FieldRep_StringView, /* BYTES */
1455
+ kUpb_FieldRep_4Byte, /* UINT32 */
1456
+ kUpb_FieldRep_4Byte, /* ENUM */
1457
+ kUpb_FieldRep_4Byte, /* SFIXED32 */
1458
+ kUpb_FieldRep_8Byte, /* SFIXED64 */
1459
+ kUpb_FieldRep_4Byte, /* SINT32 */
1460
+ kUpb_FieldRep_8Byte, /* SINT64 */
1461
+ };
1462
+ field->mode = kUpb_FieldMode_Scalar |
1463
+ (sizes[field->descriptortype] << kUpb_FieldRep_Shift);
1464
+ }
1465
+
1466
+ if (upb_FieldDef_IsPacked(f)) {
1467
+ field->mode |= kUpb_LabelFlags_IsPacked;
1468
+ }
1469
+
1470
+ if (upb_FieldDef_IsExtension(f)) {
1471
+ field->mode |= kUpb_LabelFlags_IsExtension;
1472
+ }
1473
+ }
1474
+
1475
+ /* This function is the dynamic equivalent of message_layout.{cc,h} in upbc.
1476
+ * It computes a dynamic layout for all of the fields in |m|. */
1477
+ static void make_layout(symtab_addctx* ctx, const upb_MessageDef* m) {
1478
+ upb_MiniTable* l = (upb_MiniTable*)m->layout;
1479
+ size_t field_count = upb_MessageDef_numfields(m);
1480
+ size_t sublayout_count = 0;
1481
+ upb_MiniTable_Sub* subs;
1482
+ upb_MiniTable_Field* fields;
1483
+
1484
+ memset(l, 0, sizeof(*l) + sizeof(_upb_FastTable_Entry));
1485
+
1486
+ /* Count sub-messages. */
1487
+ for (size_t i = 0; i < field_count; i++) {
1488
+ const upb_FieldDef* f = &m->fields[i];
1489
+ if (upb_FieldDef_IsSubMessage(f)) {
1490
+ sublayout_count++;
1491
+ }
1492
+ if (upb_FieldDef_CType(f) == kUpb_CType_Enum &&
1493
+ f->sub.enumdef->file->syntax == kUpb_Syntax_Proto2) {
1494
+ sublayout_count++;
1495
+ }
1496
+ }
1497
+
1498
+ fields = symtab_alloc(ctx, field_count * sizeof(*fields));
1499
+ subs = symtab_alloc(ctx, sublayout_count * sizeof(*subs));
1500
+
1501
+ l->field_count = upb_MessageDef_numfields(m);
1502
+ l->fields = fields;
1503
+ l->subs = subs;
1504
+ l->table_mask = 0;
1505
+ l->required_count = 0;
1506
+
1507
+ if (upb_MessageDef_ExtensionRangeCount(m) > 0) {
1508
+ if (google_protobuf_MessageOptions_message_set_wire_format(m->opts)) {
1509
+ l->ext = kUpb_ExtMode_IsMessageSet;
1510
+ } else {
1511
+ l->ext = kUpb_ExtMode_Extendable;
1512
+ }
1513
+ } else {
1514
+ l->ext = kUpb_ExtMode_NonExtendable;
1515
+ }
1516
+
1517
+ /* TODO(haberman): initialize fast tables so that reflection-based parsing
1518
+ * can get the same speeds as linked-in types. */
1519
+ l->fasttable[0].field_parser = &fastdecode_generic;
1520
+ l->fasttable[0].field_data = 0;
1521
+
1522
+ if (upb_MessageDef_IsMapEntry(m)) {
1523
+ /* TODO(haberman): refactor this method so this special case is more
1524
+ * elegant. */
1525
+ const upb_FieldDef* key = upb_MessageDef_FindFieldByNumber(m, 1);
1526
+ const upb_FieldDef* val = upb_MessageDef_FindFieldByNumber(m, 2);
1527
+ fields[0].number = 1;
1528
+ fields[1].number = 2;
1529
+ fields[0].mode = kUpb_FieldMode_Scalar;
1530
+ fields[1].mode = kUpb_FieldMode_Scalar;
1531
+ fields[0].presence = 0;
1532
+ fields[1].presence = 0;
1533
+ fields[0].descriptortype = map_descriptortype(key);
1534
+ fields[1].descriptortype = map_descriptortype(val);
1535
+ fields[0].offset = 0;
1536
+ fields[1].offset = sizeof(upb_StringView);
1537
+ fields[1].submsg_index = 0;
1538
+
1539
+ if (upb_FieldDef_CType(val) == kUpb_CType_Message) {
1540
+ subs[0].submsg = upb_FieldDef_MessageSubDef(val)->layout;
1541
+ }
1542
+
1543
+ upb_FieldDef* fielddefs = (upb_FieldDef*)&m->fields[0];
1544
+ UPB_ASSERT(fielddefs[0].number_ == 1);
1545
+ UPB_ASSERT(fielddefs[1].number_ == 2);
1546
+ fielddefs[0].layout_index = 0;
1547
+ fielddefs[1].layout_index = 1;
1548
+
1549
+ l->field_count = 2;
1550
+ l->size = 2 * sizeof(upb_StringView);
1551
+ l->size = UPB_ALIGN_UP(l->size, 8);
1552
+ l->dense_below = 2;
1553
+ return;
1554
+ }
1555
+
1556
+ /* Allocate data offsets in three stages:
1557
+ *
1558
+ * 1. hasbits.
1559
+ * 2. regular fields.
1560
+ * 3. oneof fields.
1561
+ *
1562
+ * OPT: There is a lot of room for optimization here to minimize the size.
1563
+ */
1564
+
1565
+ /* Assign hasbits for required fields first. */
1566
+ size_t hasbit = 0;
1567
+
1568
+ for (int i = 0; i < m->field_count; i++) {
1569
+ const upb_FieldDef* f = &m->fields[i];
1570
+ upb_MiniTable_Field* field = &fields[upb_FieldDef_Index(f)];
1571
+ if (upb_FieldDef_Label(f) == kUpb_Label_Required) {
1572
+ field->presence = ++hasbit;
1573
+ if (hasbit >= 63) {
1574
+ symtab_errf(ctx, "Message with >=63 required fields: %s",
1575
+ upb_MessageDef_FullName(m));
1576
+ }
1577
+ l->required_count++;
1578
+ }
1579
+ }
1580
+
1581
+ /* Allocate hasbits and set basic field attributes. */
1582
+ sublayout_count = 0;
1583
+ for (int i = 0; i < m->field_count; i++) {
1584
+ const upb_FieldDef* f = &m->fields[i];
1585
+ upb_MiniTable_Field* field = &fields[upb_FieldDef_Index(f)];
1586
+
1587
+ fill_fieldlayout(field, f);
1588
+
1589
+ if (field->descriptortype == kUpb_FieldType_Message ||
1590
+ field->descriptortype == kUpb_FieldType_Group) {
1591
+ field->submsg_index = sublayout_count++;
1592
+ subs[field->submsg_index].submsg = upb_FieldDef_MessageSubDef(f)->layout;
1593
+ } else if (field->descriptortype == kUpb_FieldType_Enum) {
1594
+ field->submsg_index = sublayout_count++;
1595
+ subs[field->submsg_index].subenum = upb_FieldDef_EnumSubDef(f)->layout;
1596
+ UPB_ASSERT(subs[field->submsg_index].subenum);
1597
+ }
1598
+
1599
+ if (upb_FieldDef_Label(f) == kUpb_Label_Required) {
1600
+ /* Hasbit was already assigned. */
1601
+ } else if (upb_FieldDef_HasPresence(f) &&
1602
+ !upb_FieldDef_RealContainingOneof(f)) {
1603
+ /* We don't use hasbit 0, so that 0 can indicate "no presence" in the
1604
+ * table. This wastes one hasbit, but we don't worry about it for now. */
1605
+ field->presence = ++hasbit;
1606
+ } else {
1607
+ field->presence = 0;
1608
+ }
1609
+ }
1610
+
1611
+ /* Account for space used by hasbits. */
1612
+ l->size = hasbit ? div_round_up(hasbit + 1, 8) : 0;
1613
+
1614
+ /* Allocate non-oneof fields. */
1615
+ for (int i = 0; i < m->field_count; i++) {
1616
+ const upb_FieldDef* f = &m->fields[i];
1617
+ size_t field_size = upb_msg_fielddefsize(f);
1618
+ size_t index = upb_FieldDef_Index(f);
1619
+
1620
+ if (upb_FieldDef_RealContainingOneof(f)) {
1621
+ /* Oneofs are handled separately below. */
1622
+ continue;
1623
+ }
1624
+
1625
+ fields[index].offset = upb_MiniTable_place(ctx, l, field_size, m);
1626
+ }
1627
+
1628
+ /* Allocate oneof fields. Each oneof field consists of a uint32 for the case
1629
+ * and space for the actual data. */
1630
+ for (int i = 0; i < m->oneof_count; i++) {
1631
+ const upb_OneofDef* o = &m->oneofs[i];
1632
+ size_t case_size = sizeof(uint32_t); /* Could potentially optimize this. */
1633
+ size_t field_size = 0;
1634
+ uint32_t case_offset;
1635
+ uint32_t data_offset;
1636
+
1637
+ if (upb_OneofDef_IsSynthetic(o)) continue;
1638
+
1639
+ if (o->field_count == 0) {
1640
+ symtab_errf(ctx, "Oneof must have at least one field (%s)", o->full_name);
1641
+ }
1642
+
1643
+ /* Calculate field size: the max of all field sizes. */
1644
+ for (int j = 0; j < o->field_count; j++) {
1645
+ const upb_FieldDef* f = o->fields[j];
1646
+ field_size = UPB_MAX(field_size, upb_msg_fielddefsize(f));
1647
+ }
1648
+
1649
+ /* Align and allocate case offset. */
1650
+ case_offset = upb_MiniTable_place(ctx, l, case_size, m);
1651
+ data_offset = upb_MiniTable_place(ctx, l, field_size, m);
1652
+
1653
+ for (int i = 0; i < o->field_count; i++) {
1654
+ const upb_FieldDef* f = o->fields[i];
1655
+ fields[upb_FieldDef_Index(f)].offset = data_offset;
1656
+ fields[upb_FieldDef_Index(f)].presence = ~case_offset;
1657
+ }
1658
+ }
1659
+
1660
+ /* Size of the entire structure should be a multiple of its greatest
1661
+ * alignment. TODO: track overall alignment for real? */
1662
+ l->size = UPB_ALIGN_UP(l->size, 8);
1663
+
1664
+ /* Sort fields by number. */
1665
+ if (fields) {
1666
+ qsort(fields, upb_MessageDef_numfields(m), sizeof(*fields),
1667
+ field_number_cmp);
1668
+ }
1669
+ assign_layout_indices(m, l, fields);
1670
+ }
1671
+
1672
+ static char* strviewdup(symtab_addctx* ctx, upb_StringView view) {
1673
+ char* ret = upb_strdup2(view.data, view.size, ctx->arena);
1674
+ CHK_OOM(ret);
1675
+ return ret;
1676
+ }
1677
+
1678
+ static bool streql2(const char* a, size_t n, const char* b) {
1679
+ return n == strlen(b) && memcmp(a, b, n) == 0;
1680
+ }
1681
+
1682
+ static bool streql_view(upb_StringView view, const char* b) {
1683
+ return streql2(view.data, view.size, b);
1684
+ }
1685
+
1686
+ static const char* makefullname(symtab_addctx* ctx, const char* prefix,
1687
+ upb_StringView name) {
1688
+ if (prefix) {
1689
+ /* ret = prefix + '.' + name; */
1690
+ size_t n = strlen(prefix);
1691
+ char* ret = symtab_alloc(ctx, n + name.size + 2);
1692
+ strcpy(ret, prefix);
1693
+ ret[n] = '.';
1694
+ memcpy(&ret[n + 1], name.data, name.size);
1695
+ ret[n + 1 + name.size] = '\0';
1696
+ return ret;
1697
+ } else {
1698
+ return strviewdup(ctx, name);
1699
+ }
1700
+ }
1701
+
1702
+ static void finalize_oneofs(symtab_addctx* ctx, upb_MessageDef* m) {
1703
+ int i;
1704
+ int synthetic_count = 0;
1705
+ upb_OneofDef* mutable_oneofs = (upb_OneofDef*)m->oneofs;
1706
+
1707
+ for (i = 0; i < m->oneof_count; i++) {
1708
+ upb_OneofDef* o = &mutable_oneofs[i];
1709
+
1710
+ if (o->synthetic && o->field_count != 1) {
1711
+ symtab_errf(ctx, "Synthetic oneofs must have one field, not %d: %s",
1712
+ o->field_count, upb_OneofDef_Name(o));
1713
+ }
1714
+
1715
+ if (o->synthetic) {
1716
+ synthetic_count++;
1717
+ } else if (synthetic_count != 0) {
1718
+ symtab_errf(ctx, "Synthetic oneofs must be after all other oneofs: %s",
1719
+ upb_OneofDef_Name(o));
1720
+ }
1721
+
1722
+ o->fields = symtab_alloc(ctx, sizeof(upb_FieldDef*) * o->field_count);
1723
+ o->field_count = 0;
1724
+ }
1725
+
1726
+ for (i = 0; i < m->field_count; i++) {
1727
+ const upb_FieldDef* f = &m->fields[i];
1728
+ upb_OneofDef* o = (upb_OneofDef*)upb_FieldDef_ContainingOneof(f);
1729
+ if (o) {
1730
+ o->fields[o->field_count++] = f;
1731
+ }
1732
+ }
1733
+
1734
+ m->real_oneof_count = m->oneof_count - synthetic_count;
1735
+ }
1736
+
1737
+ size_t getjsonname(const char* name, char* buf, size_t len) {
1738
+ size_t src, dst = 0;
1739
+ bool ucase_next = false;
1740
+
1741
+ #define WRITE(byte) \
1742
+ ++dst; \
1743
+ if (dst < len) \
1744
+ buf[dst - 1] = byte; \
1745
+ else if (dst == len) \
1746
+ buf[dst - 1] = '\0'
1747
+
1748
+ if (!name) {
1749
+ WRITE('\0');
1750
+ return 0;
1751
+ }
1752
+
1753
+ /* Implement the transformation as described in the spec:
1754
+ * 1. upper case all letters after an underscore.
1755
+ * 2. remove all underscores.
1756
+ */
1757
+ for (src = 0; name[src]; src++) {
1758
+ if (name[src] == '_') {
1759
+ ucase_next = true;
1760
+ continue;
1761
+ }
1762
+
1763
+ if (ucase_next) {
1764
+ WRITE(toupper(name[src]));
1765
+ ucase_next = false;
1766
+ } else {
1767
+ WRITE(name[src]);
1768
+ }
1769
+ }
1770
+
1771
+ WRITE('\0');
1772
+ return dst;
1773
+
1774
+ #undef WRITE
1775
+ }
1776
+
1777
+ static char* makejsonname(symtab_addctx* ctx, const char* name) {
1778
+ size_t size = getjsonname(name, NULL, 0);
1779
+ char* json_name = symtab_alloc(ctx, size);
1780
+ getjsonname(name, json_name, size);
1781
+ return json_name;
1782
+ }
1783
+
1784
+ /* Adds a symbol |v| to the symtab, which must be a def pointer previously
1785
+ * packed with pack_def(). The def's pointer to upb_FileDef* must be set before
1786
+ * adding, so we know which entries to remove if building this file fails. */
1787
+ static void symtab_add(symtab_addctx* ctx, const char* name, upb_value v) {
1788
+ // TODO: table should support an operation "tryinsert" to avoid the double
1789
+ // lookup.
1790
+ if (upb_strtable_lookup(&ctx->symtab->syms, name, NULL)) {
1791
+ symtab_errf(ctx, "duplicate symbol '%s'", name);
1792
+ }
1793
+ size_t len = strlen(name);
1794
+ CHK_OOM(upb_strtable_insert(&ctx->symtab->syms, name, len, v,
1795
+ ctx->symtab->arena));
1796
+ }
1797
+
1798
+ static bool remove_component(char* base, size_t* len) {
1799
+ if (*len == 0) return false;
1800
+
1801
+ for (size_t i = *len - 1; i > 0; i--) {
1802
+ if (base[i] == '.') {
1803
+ *len = i;
1804
+ return true;
1805
+ }
1806
+ }
1807
+
1808
+ *len = 0;
1809
+ return true;
1810
+ }
1811
+
1812
+ /* Given a symbol and the base symbol inside which it is defined, find the
1813
+ * symbol's definition in t. */
1814
+ static const void* symtab_resolveany(symtab_addctx* ctx,
1815
+ const char* from_name_dbg,
1816
+ const char* base, upb_StringView sym,
1817
+ upb_deftype_t* type) {
1818
+ const upb_strtable* t = &ctx->symtab->syms;
1819
+ if (sym.size == 0) goto notfound;
1820
+ upb_value v;
1821
+ if (sym.data[0] == '.') {
1822
+ /* Symbols starting with '.' are absolute, so we do a single lookup.
1823
+ * Slice to omit the leading '.' */
1824
+ if (!upb_strtable_lookup2(t, sym.data + 1, sym.size - 1, &v)) {
1825
+ goto notfound;
1826
+ }
1827
+ } else {
1828
+ /* Remove components from base until we find an entry or run out. */
1829
+ size_t baselen = base ? strlen(base) : 0;
1830
+ char* tmp = malloc(sym.size + baselen + 1);
1831
+ while (1) {
1832
+ char* p = tmp;
1833
+ if (baselen) {
1834
+ memcpy(p, base, baselen);
1835
+ p[baselen] = '.';
1836
+ p += baselen + 1;
1837
+ }
1838
+ memcpy(p, sym.data, sym.size);
1839
+ p += sym.size;
1840
+ if (upb_strtable_lookup2(t, tmp, p - tmp, &v)) {
1841
+ break;
1842
+ }
1843
+ if (!remove_component(tmp, &baselen)) {
1844
+ free(tmp);
1845
+ goto notfound;
1846
+ }
1847
+ }
1848
+ free(tmp);
1849
+ }
1850
+
1851
+ *type = deftype(v);
1852
+ return unpack_def(v, *type);
1853
+
1854
+ notfound:
1855
+ symtab_errf(ctx, "couldn't resolve name '" UPB_STRINGVIEW_FORMAT "'",
1856
+ UPB_STRINGVIEW_ARGS(sym));
1857
+ }
1858
+
1859
+ static const void* symtab_resolve(symtab_addctx* ctx, const char* from_name_dbg,
1860
+ const char* base, upb_StringView sym,
1861
+ upb_deftype_t type) {
1862
+ upb_deftype_t found_type;
1863
+ const void* ret =
1864
+ symtab_resolveany(ctx, from_name_dbg, base, sym, &found_type);
1865
+ if (ret && found_type != type) {
1866
+ symtab_errf(ctx,
1867
+ "type mismatch when resolving %s: couldn't find "
1868
+ "name " UPB_STRINGVIEW_FORMAT " with type=%d",
1869
+ from_name_dbg, UPB_STRINGVIEW_ARGS(sym), (int)type);
1870
+ }
1871
+ return ret;
1872
+ }
1873
+
1874
+ static void create_oneofdef(
1875
+ symtab_addctx* ctx, upb_MessageDef* m,
1876
+ const google_protobuf_OneofDescriptorProto* oneof_proto,
1877
+ const upb_OneofDef* _o) {
1878
+ upb_OneofDef* o = (upb_OneofDef*)_o;
1879
+ upb_StringView name = google_protobuf_OneofDescriptorProto_name(oneof_proto);
1880
+ upb_value v;
1881
+
1882
+ o->parent = m;
1883
+ o->full_name = makefullname(ctx, m->full_name, name);
1884
+ o->field_count = 0;
1885
+ o->synthetic = false;
1886
+
1887
+ SET_OPTIONS(o->opts, OneofDescriptorProto, OneofOptions, oneof_proto);
1888
+
1889
+ upb_value existing_v;
1890
+ if (upb_strtable_lookup2(&m->ntof, name.data, name.size, &existing_v)) {
1891
+ symtab_errf(ctx, "duplicate oneof name (%s)", o->full_name);
1892
+ }
1893
+
1894
+ v = pack_def(o, UPB_DEFTYPE_ONEOF);
1895
+ CHK_OOM(upb_strtable_insert(&m->ntof, name.data, name.size, v, ctx->arena));
1896
+
1897
+ CHK_OOM(upb_inttable_init(&o->itof, ctx->arena));
1898
+ CHK_OOM(upb_strtable_init(&o->ntof, 4, ctx->arena));
1899
+ }
1900
+
1901
+ static str_t* newstr(symtab_addctx* ctx, const char* data, size_t len) {
1902
+ str_t* ret = symtab_alloc(ctx, sizeof(*ret) + len);
1903
+ CHK_OOM(ret);
1904
+ ret->len = len;
1905
+ if (len) memcpy(ret->str, data, len);
1906
+ ret->str[len] = '\0';
1907
+ return ret;
1908
+ }
1909
+
1910
+ static bool upb_DefPool_TryGetChar(const char** src, const char* end,
1911
+ char* ch) {
1912
+ if (*src == end) return false;
1913
+ *ch = **src;
1914
+ *src += 1;
1915
+ return true;
1916
+ }
1917
+
1918
+ static char upb_DefPool_TryGetHexDigit(symtab_addctx* ctx,
1919
+ const upb_FieldDef* f, const char** src,
1920
+ const char* end) {
1921
+ char ch;
1922
+ if (!upb_DefPool_TryGetChar(src, end, &ch)) return -1;
1923
+ if ('0' <= ch && ch <= '9') {
1924
+ return ch - '0';
1925
+ }
1926
+ ch = upb_ascii_lower(ch);
1927
+ if ('a' <= ch && ch <= 'f') {
1928
+ return ch - 'a' + 0xa;
1929
+ }
1930
+ *src -= 1; // Char wasn't actually a hex digit.
1931
+ return -1;
1932
+ }
1933
+
1934
+ static char upb_DefPool_ParseHexEscape(symtab_addctx* ctx,
1935
+ const upb_FieldDef* f, const char** src,
1936
+ const char* end) {
1937
+ char hex_digit = upb_DefPool_TryGetHexDigit(ctx, f, src, end);
1938
+ if (hex_digit < 0) {
1939
+ symtab_errf(ctx,
1940
+ "\\x cannot be followed by non-hex digit in field '%s' default",
1941
+ upb_FieldDef_FullName(f));
1942
+ return 0;
1943
+ }
1944
+ unsigned int ret = hex_digit;
1945
+ while ((hex_digit = upb_DefPool_TryGetHexDigit(ctx, f, src, end)) >= 0) {
1946
+ ret = (ret << 4) | hex_digit;
1947
+ }
1948
+ if (ret > 0xff) {
1949
+ symtab_errf(ctx, "Value of hex escape in field %s exceeds 8 bits",
1950
+ upb_FieldDef_FullName(f));
1951
+ return 0;
1952
+ }
1953
+ return ret;
1954
+ }
1955
+
1956
+ char upb_DefPool_TryGetOctalDigit(const char** src, const char* end) {
1957
+ char ch;
1958
+ if (!upb_DefPool_TryGetChar(src, end, &ch)) return -1;
1959
+ if ('0' <= ch && ch <= '7') {
1960
+ return ch - '0';
1961
+ }
1962
+ *src -= 1; // Char wasn't actually an octal digit.
1963
+ return -1;
1964
+ }
1965
+
1966
+ static char upb_DefPool_ParseOctalEscape(symtab_addctx* ctx,
1967
+ const upb_FieldDef* f,
1968
+ const char** src, const char* end) {
1969
+ char ch = 0;
1970
+ for (int i = 0; i < 3; i++) {
1971
+ char digit;
1972
+ if ((digit = upb_DefPool_TryGetOctalDigit(src, end)) >= 0) {
1973
+ ch = (ch << 3) | digit;
1974
+ }
1975
+ }
1976
+ return ch;
1977
+ }
1978
+
1979
+ static char upb_DefPool_ParseEscape(symtab_addctx* ctx, const upb_FieldDef* f,
1980
+ const char** src, const char* end) {
1981
+ char ch;
1982
+ if (!upb_DefPool_TryGetChar(src, end, &ch)) {
1983
+ symtab_errf(ctx, "unterminated escape sequence in field %s",
1984
+ upb_FieldDef_FullName(f));
1985
+ return 0;
1986
+ }
1987
+ switch (ch) {
1988
+ case 'a':
1989
+ return '\a';
1990
+ case 'b':
1991
+ return '\b';
1992
+ case 'f':
1993
+ return '\f';
1994
+ case 'n':
1995
+ return '\n';
1996
+ case 'r':
1997
+ return '\r';
1998
+ case 't':
1999
+ return '\t';
2000
+ case 'v':
2001
+ return '\v';
2002
+ case '\\':
2003
+ return '\\';
2004
+ case '\'':
2005
+ return '\'';
2006
+ case '\"':
2007
+ return '\"';
2008
+ case '?':
2009
+ return '\?';
2010
+ case 'x':
2011
+ case 'X':
2012
+ return upb_DefPool_ParseHexEscape(ctx, f, src, end);
2013
+ case '0':
2014
+ case '1':
2015
+ case '2':
2016
+ case '3':
2017
+ case '4':
2018
+ case '5':
2019
+ case '6':
2020
+ case '7':
2021
+ *src -= 1;
2022
+ return upb_DefPool_ParseOctalEscape(ctx, f, src, end);
2023
+ }
2024
+ symtab_errf(ctx, "Unknown escape sequence: \\%c", ch);
2025
+ }
2026
+
2027
+ static str_t* unescape(symtab_addctx* ctx, const upb_FieldDef* f,
2028
+ const char* data, size_t len) {
2029
+ // Size here is an upper bound; escape sequences could ultimately shrink it.
2030
+ str_t* ret = symtab_alloc(ctx, sizeof(*ret) + len);
2031
+ char* dst = &ret->str[0];
2032
+ const char* src = data;
2033
+ const char* end = data + len;
2034
+
2035
+ while (src < end) {
2036
+ if (*src == '\\') {
2037
+ src++;
2038
+ *dst++ = upb_DefPool_ParseEscape(ctx, f, &src, end);
2039
+ } else {
2040
+ *dst++ = *src++;
2041
+ }
2042
+ }
2043
+
2044
+ ret->len = dst - &ret->str[0];
2045
+ return ret;
2046
+ }
2047
+
2048
+ static void parse_default(symtab_addctx* ctx, const char* str, size_t len,
2049
+ upb_FieldDef* f) {
2050
+ char* end;
2051
+ char nullz[64];
2052
+ errno = 0;
2053
+
2054
+ switch (upb_FieldDef_CType(f)) {
2055
+ case kUpb_CType_Int32:
2056
+ case kUpb_CType_Int64:
2057
+ case kUpb_CType_UInt32:
2058
+ case kUpb_CType_UInt64:
2059
+ case kUpb_CType_Double:
2060
+ case kUpb_CType_Float:
2061
+ /* Standard C number parsing functions expect null-terminated strings. */
2062
+ if (len >= sizeof(nullz) - 1) {
2063
+ symtab_errf(ctx, "Default too long: %.*s", (int)len, str);
2064
+ }
2065
+ memcpy(nullz, str, len);
2066
+ nullz[len] = '\0';
2067
+ str = nullz;
2068
+ break;
2069
+ default:
2070
+ break;
2071
+ }
2072
+
2073
+ switch (upb_FieldDef_CType(f)) {
2074
+ case kUpb_CType_Int32: {
2075
+ long val = strtol(str, &end, 0);
2076
+ if (val > INT32_MAX || val < INT32_MIN || errno == ERANGE || *end) {
2077
+ goto invalid;
2078
+ }
2079
+ f->defaultval.sint = val;
2080
+ break;
2081
+ }
2082
+ case kUpb_CType_Enum: {
2083
+ const upb_EnumDef* e = f->sub.enumdef;
2084
+ const upb_EnumValueDef* ev =
2085
+ upb_EnumDef_FindValueByNameWithSize(e, str, len);
2086
+ if (!ev) {
2087
+ goto invalid;
2088
+ }
2089
+ f->defaultval.sint = ev->number;
2090
+ break;
2091
+ }
2092
+ case kUpb_CType_Int64: {
2093
+ long long val = strtoll(str, &end, 0);
2094
+ if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end) {
2095
+ goto invalid;
2096
+ }
2097
+ f->defaultval.sint = val;
2098
+ break;
2099
+ }
2100
+ case kUpb_CType_UInt32: {
2101
+ unsigned long val = strtoul(str, &end, 0);
2102
+ if (val > UINT32_MAX || errno == ERANGE || *end) {
2103
+ goto invalid;
2104
+ }
2105
+ f->defaultval.uint = val;
2106
+ break;
2107
+ }
2108
+ case kUpb_CType_UInt64: {
2109
+ unsigned long long val = strtoull(str, &end, 0);
2110
+ if (val > UINT64_MAX || errno == ERANGE || *end) {
2111
+ goto invalid;
2112
+ }
2113
+ f->defaultval.uint = val;
2114
+ break;
2115
+ }
2116
+ case kUpb_CType_Double: {
2117
+ double val = strtod(str, &end);
2118
+ if (errno == ERANGE || *end) {
2119
+ goto invalid;
2120
+ }
2121
+ f->defaultval.dbl = val;
2122
+ break;
2123
+ }
2124
+ case kUpb_CType_Float: {
2125
+ float val = strtof(str, &end);
2126
+ if (errno == ERANGE || *end) {
2127
+ goto invalid;
2128
+ }
2129
+ f->defaultval.flt = val;
2130
+ break;
2131
+ }
2132
+ case kUpb_CType_Bool: {
2133
+ if (streql2(str, len, "false")) {
2134
+ f->defaultval.boolean = false;
2135
+ } else if (streql2(str, len, "true")) {
2136
+ f->defaultval.boolean = true;
2137
+ } else {
2138
+ goto invalid;
2139
+ }
2140
+ break;
2141
+ }
2142
+ case kUpb_CType_String:
2143
+ f->defaultval.str = newstr(ctx, str, len);
2144
+ break;
2145
+ case kUpb_CType_Bytes:
2146
+ f->defaultval.str = unescape(ctx, f, str, len);
2147
+ break;
2148
+ case kUpb_CType_Message:
2149
+ /* Should not have a default value. */
2150
+ symtab_errf(ctx, "Message should not have a default (%s)",
2151
+ upb_FieldDef_FullName(f));
2152
+ }
2153
+
2154
+ return;
2155
+
2156
+ invalid:
2157
+ symtab_errf(ctx, "Invalid default '%.*s' for field %s of type %d", (int)len,
2158
+ str, upb_FieldDef_FullName(f), (int)upb_FieldDef_Type(f));
2159
+ }
2160
+
2161
+ static void set_default_default(symtab_addctx* ctx, upb_FieldDef* f) {
2162
+ switch (upb_FieldDef_CType(f)) {
2163
+ case kUpb_CType_Int32:
2164
+ case kUpb_CType_Int64:
2165
+ f->defaultval.sint = 0;
2166
+ break;
2167
+ case kUpb_CType_UInt64:
2168
+ case kUpb_CType_UInt32:
2169
+ f->defaultval.uint = 0;
2170
+ break;
2171
+ case kUpb_CType_Double:
2172
+ case kUpb_CType_Float:
2173
+ f->defaultval.dbl = 0;
2174
+ break;
2175
+ case kUpb_CType_String:
2176
+ case kUpb_CType_Bytes:
2177
+ f->defaultval.str = newstr(ctx, NULL, 0);
2178
+ break;
2179
+ case kUpb_CType_Bool:
2180
+ f->defaultval.boolean = false;
2181
+ break;
2182
+ case kUpb_CType_Enum:
2183
+ f->defaultval.sint = f->sub.enumdef->values[0].number;
2184
+ case kUpb_CType_Message:
2185
+ break;
2186
+ }
2187
+ }
2188
+
2189
+ static void create_fielddef(
2190
+ symtab_addctx* ctx, const char* prefix, upb_MessageDef* m,
2191
+ const google_protobuf_FieldDescriptorProto* field_proto,
2192
+ const upb_FieldDef* _f, bool is_extension) {
2193
+ upb_FieldDef* f = (upb_FieldDef*)_f;
2194
+ upb_StringView name;
2195
+ const char* full_name;
2196
+ const char* json_name;
2197
+ const char* shortname;
2198
+ int32_t field_number;
2199
+
2200
+ f->file = ctx->file; /* Must happen prior to symtab_add(). */
2201
+
2202
+ if (!google_protobuf_FieldDescriptorProto_has_name(field_proto)) {
2203
+ symtab_errf(ctx, "field has no name");
2204
+ }
2205
+
2206
+ name = google_protobuf_FieldDescriptorProto_name(field_proto);
2207
+ check_ident(ctx, name, false);
2208
+ full_name = makefullname(ctx, prefix, name);
2209
+ shortname = shortdefname(full_name);
2210
+
2211
+ if (google_protobuf_FieldDescriptorProto_has_json_name(field_proto)) {
2212
+ json_name = strviewdup(
2213
+ ctx, google_protobuf_FieldDescriptorProto_json_name(field_proto));
2214
+ f->has_json_name_ = true;
2215
+ } else {
2216
+ json_name = makejsonname(ctx, shortname);
2217
+ f->has_json_name_ = false;
2218
+ }
2219
+
2220
+ field_number = google_protobuf_FieldDescriptorProto_number(field_proto);
2221
+
2222
+ f->full_name = full_name;
2223
+ f->json_name = json_name;
2224
+ f->label_ = (int)google_protobuf_FieldDescriptorProto_label(field_proto);
2225
+ f->number_ = field_number;
2226
+ f->scope.oneof = NULL;
2227
+ f->proto3_optional_ =
2228
+ google_protobuf_FieldDescriptorProto_proto3_optional(field_proto);
2229
+
2230
+ bool has_type = google_protobuf_FieldDescriptorProto_has_type(field_proto);
2231
+ bool has_type_name =
2232
+ google_protobuf_FieldDescriptorProto_has_type_name(field_proto);
2233
+
2234
+ f->type_ = (int)google_protobuf_FieldDescriptorProto_type(field_proto);
2235
+
2236
+ if (has_type) {
2237
+ switch (f->type_) {
2238
+ case kUpb_FieldType_Message:
2239
+ case kUpb_FieldType_Group:
2240
+ case kUpb_FieldType_Enum:
2241
+ if (!has_type_name) {
2242
+ symtab_errf(ctx, "field of type %d requires type name (%s)",
2243
+ (int)f->type_, full_name);
2244
+ }
2245
+ break;
2246
+ default:
2247
+ if (has_type_name) {
2248
+ symtab_errf(ctx, "invalid type for field with type_name set (%s, %d)",
2249
+ full_name, (int)f->type_);
2250
+ }
2251
+ }
2252
+ } else if (has_type_name) {
2253
+ f->type_ =
2254
+ FIELD_TYPE_UNSPECIFIED; // We'll fill this in in resolve_fielddef().
2255
+ }
2256
+
2257
+ if (!is_extension) {
2258
+ /* direct message field. */
2259
+ upb_value v, field_v, json_v, existing_v;
2260
+ size_t json_size;
2261
+
2262
+ if (field_number <= 0 || field_number > kUpb_MaxFieldNumber) {
2263
+ symtab_errf(ctx, "invalid field number (%u)", field_number);
2264
+ }
2265
+
2266
+ f->index_ = f - m->fields;
2267
+ f->msgdef = m;
2268
+ f->is_extension_ = false;
2269
+
2270
+ field_v = pack_def(f, UPB_DEFTYPE_FIELD);
2271
+ json_v = pack_def(f, UPB_DEFTYPE_FIELD_JSONNAME);
2272
+ v = upb_value_constptr(f);
2273
+ json_size = strlen(json_name);
2274
+
2275
+ if (upb_strtable_lookup(&m->ntof, shortname, &existing_v)) {
2276
+ symtab_errf(ctx, "duplicate field name (%s)", shortname);
2277
+ }
2278
+
2279
+ CHK_OOM(upb_strtable_insert(&m->ntof, name.data, name.size, field_v,
2280
+ ctx->arena));
2281
+
2282
+ if (strcmp(shortname, json_name) != 0) {
2283
+ if (upb_strtable_lookup(&m->ntof, json_name, &v)) {
2284
+ symtab_errf(ctx, "duplicate json_name (%s)", json_name);
2285
+ } else {
2286
+ CHK_OOM(upb_strtable_insert(&m->ntof, json_name, json_size, json_v,
2287
+ ctx->arena));
2288
+ }
2289
+ }
2290
+
2291
+ if (upb_inttable_lookup(&m->itof, field_number, NULL)) {
2292
+ symtab_errf(ctx, "duplicate field number (%u)", field_number);
2293
+ }
2294
+
2295
+ CHK_OOM(upb_inttable_insert(&m->itof, field_number, v, ctx->arena));
2296
+
2297
+ if (ctx->layout) {
2298
+ const upb_MiniTable_Field* fields = m->layout->fields;
2299
+ int count = m->layout->field_count;
2300
+ bool found = false;
2301
+ for (int i = 0; i < count; i++) {
2302
+ if (fields[i].number == field_number) {
2303
+ f->layout_index = i;
2304
+ found = true;
2305
+ break;
2306
+ }
2307
+ }
2308
+ UPB_ASSERT(found);
2309
+ }
2310
+ } else {
2311
+ /* extension field. */
2312
+ f->is_extension_ = true;
2313
+ f->scope.extension_scope = m;
2314
+ symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_EXT));
2315
+ f->layout_index = ctx->ext_count++;
2316
+ if (ctx->layout) {
2317
+ UPB_ASSERT(ctx->file->ext_layouts[f->layout_index]->field.number ==
2318
+ field_number);
2319
+ }
2320
+ }
2321
+
2322
+ if (f->type_ < kUpb_FieldType_Double || f->type_ > kUpb_FieldType_SInt64) {
2323
+ symtab_errf(ctx, "invalid type for field %s (%d)", f->full_name, f->type_);
2324
+ }
2325
+
2326
+ if (f->label_ < kUpb_Label_Optional || f->label_ > kUpb_Label_Repeated) {
2327
+ symtab_errf(ctx, "invalid label for field %s (%d)", f->full_name,
2328
+ f->label_);
2329
+ }
2330
+
2331
+ /* We can't resolve the subdef or (in the case of extensions) the containing
2332
+ * message yet, because it may not have been defined yet. We stash a pointer
2333
+ * to the field_proto until later when we can properly resolve it. */
2334
+ f->sub.unresolved = field_proto;
2335
+
2336
+ if (f->label_ == kUpb_Label_Required &&
2337
+ f->file->syntax == kUpb_Syntax_Proto3) {
2338
+ symtab_errf(ctx, "proto3 fields cannot be required (%s)", f->full_name);
2339
+ }
2340
+
2341
+ if (google_protobuf_FieldDescriptorProto_has_oneof_index(field_proto)) {
2342
+ int oneof_index =
2343
+ google_protobuf_FieldDescriptorProto_oneof_index(field_proto);
2344
+ upb_OneofDef* oneof;
2345
+ upb_value v = upb_value_constptr(f);
2346
+
2347
+ if (upb_FieldDef_Label(f) != kUpb_Label_Optional) {
2348
+ symtab_errf(ctx, "fields in oneof must have OPTIONAL label (%s)",
2349
+ f->full_name);
2350
+ }
2351
+
2352
+ if (!m) {
2353
+ symtab_errf(ctx, "oneof_index provided for extension field (%s)",
2354
+ f->full_name);
2355
+ }
2356
+
2357
+ if (oneof_index >= m->oneof_count) {
2358
+ symtab_errf(ctx, "oneof_index out of range (%s)", f->full_name);
2359
+ }
2360
+
2361
+ oneof = (upb_OneofDef*)&m->oneofs[oneof_index];
2362
+ f->scope.oneof = oneof;
2363
+
2364
+ oneof->field_count++;
2365
+ if (f->proto3_optional_) {
2366
+ oneof->synthetic = true;
2367
+ }
2368
+ CHK_OOM(upb_inttable_insert(&oneof->itof, f->number_, v, ctx->arena));
2369
+ CHK_OOM(
2370
+ upb_strtable_insert(&oneof->ntof, name.data, name.size, v, ctx->arena));
2371
+ } else {
2372
+ if (f->proto3_optional_) {
2373
+ symtab_errf(ctx, "field with proto3_optional was not in a oneof (%s)",
2374
+ f->full_name);
2375
+ }
2376
+ }
2377
+
2378
+ SET_OPTIONS(f->opts, FieldDescriptorProto, FieldOptions, field_proto);
2379
+
2380
+ if (google_protobuf_FieldOptions_has_packed(f->opts)) {
2381
+ f->packed_ = google_protobuf_FieldOptions_packed(f->opts);
2382
+ } else {
2383
+ /* Repeated fields default to packed for proto3 only. */
2384
+ f->packed_ = upb_FieldDef_IsPrimitive(f) &&
2385
+ f->label_ == kUpb_Label_Repeated &&
2386
+ f->file->syntax == kUpb_Syntax_Proto3;
2387
+ }
2388
+ }
2389
+
2390
+ static void create_service(
2391
+ symtab_addctx* ctx, const google_protobuf_ServiceDescriptorProto* svc_proto,
2392
+ const upb_ServiceDef* _s) {
2393
+ upb_ServiceDef* s = (upb_ServiceDef*)_s;
2394
+ upb_StringView name;
2395
+ const google_protobuf_MethodDescriptorProto* const* methods;
2396
+ size_t i, n;
2397
+
2398
+ s->file = ctx->file; /* Must happen prior to symtab_add. */
2399
+
2400
+ name = google_protobuf_ServiceDescriptorProto_name(svc_proto);
2401
+ check_ident(ctx, name, false);
2402
+ s->full_name = makefullname(ctx, ctx->file->package, name);
2403
+ symtab_add(ctx, s->full_name, pack_def(s, UPB_DEFTYPE_SERVICE));
2404
+
2405
+ methods = google_protobuf_ServiceDescriptorProto_method(svc_proto, &n);
2406
+
2407
+ s->method_count = n;
2408
+ s->methods = symtab_alloc(ctx, sizeof(*s->methods) * n);
2409
+
2410
+ SET_OPTIONS(s->opts, ServiceDescriptorProto, ServiceOptions, svc_proto);
2411
+
2412
+ for (i = 0; i < n; i++) {
2413
+ const google_protobuf_MethodDescriptorProto* method_proto = methods[i];
2414
+ upb_MethodDef* m = (upb_MethodDef*)&s->methods[i];
2415
+ upb_StringView name =
2416
+ google_protobuf_MethodDescriptorProto_name(method_proto);
2417
+
2418
+ m->service = s;
2419
+ m->full_name = makefullname(ctx, s->full_name, name);
2420
+ m->index = i;
2421
+ m->client_streaming =
2422
+ google_protobuf_MethodDescriptorProto_client_streaming(method_proto);
2423
+ m->server_streaming =
2424
+ google_protobuf_MethodDescriptorProto_server_streaming(method_proto);
2425
+ m->input_type = symtab_resolve(
2426
+ ctx, m->full_name, m->full_name,
2427
+ google_protobuf_MethodDescriptorProto_input_type(method_proto),
2428
+ UPB_DEFTYPE_MSG);
2429
+ m->output_type = symtab_resolve(
2430
+ ctx, m->full_name, m->full_name,
2431
+ google_protobuf_MethodDescriptorProto_output_type(method_proto),
2432
+ UPB_DEFTYPE_MSG);
2433
+
2434
+ SET_OPTIONS(m->opts, MethodDescriptorProto, MethodOptions, method_proto);
2435
+ }
2436
+ }
2437
+
2438
+ static int count_bits_debug(uint64_t x) {
2439
+ // For assertions only, speed does not matter.
2440
+ int n = 0;
2441
+ while (x) {
2442
+ if (x & 1) n++;
2443
+ x >>= 1;
2444
+ }
2445
+ return n;
2446
+ }
2447
+
2448
+ static int compare_int32(const void* a_ptr, const void* b_ptr) {
2449
+ int32_t a = *(int32_t*)a_ptr;
2450
+ int32_t b = *(int32_t*)b_ptr;
2451
+ return a < b ? -1 : (a == b ? 0 : 1);
2452
+ }
2453
+
2454
+ upb_MiniTable_Enum* create_enumlayout(symtab_addctx* ctx,
2455
+ const upb_EnumDef* e) {
2456
+ int n = 0;
2457
+ uint64_t mask = 0;
2458
+
2459
+ for (int i = 0; i < e->value_count; i++) {
2460
+ uint32_t val = (uint32_t)e->values[i].number;
2461
+ if (val < 64) {
2462
+ mask |= 1ULL << val;
2463
+ } else {
2464
+ n++;
2465
+ }
2466
+ }
2467
+
2468
+ int32_t* values = symtab_alloc(ctx, sizeof(*values) * n);
2469
+
2470
+ if (n) {
2471
+ int32_t* p = values;
2472
+
2473
+ // Add values outside the bitmask range to the list, as described in the
2474
+ // comments for upb_MiniTable_Enum.
2475
+ for (int i = 0; i < e->value_count; i++) {
2476
+ int32_t val = e->values[i].number;
2477
+ if ((uint32_t)val >= 64) {
2478
+ *p++ = val;
2479
+ }
2480
+ }
2481
+ UPB_ASSERT(p == values + n);
2482
+ }
2483
+
2484
+ // Enums can have duplicate values; we must sort+uniq them.
2485
+ if (values) qsort(values, n, sizeof(*values), &compare_int32);
2486
+
2487
+ int dst = 0;
2488
+ for (int i = 0; i < n; dst++) {
2489
+ int32_t val = values[i];
2490
+ while (i < n && values[i] == val) i++; // Skip duplicates.
2491
+ values[dst] = val;
2492
+ }
2493
+ n = dst;
2494
+
2495
+ UPB_ASSERT(upb_inttable_count(&e->iton) == n + count_bits_debug(mask));
2496
+
2497
+ upb_MiniTable_Enum* layout = symtab_alloc(ctx, sizeof(*layout));
2498
+ layout->value_count = n;
2499
+ layout->mask = mask;
2500
+ layout->values = values;
2501
+
2502
+ return layout;
2503
+ }
2504
+
2505
+ static void create_enumvaldef(
2506
+ symtab_addctx* ctx, const char* prefix,
2507
+ const google_protobuf_EnumValueDescriptorProto* val_proto, upb_EnumDef* e,
2508
+ int i) {
2509
+ upb_EnumValueDef* val = (upb_EnumValueDef*)&e->values[i];
2510
+ upb_StringView name =
2511
+ google_protobuf_EnumValueDescriptorProto_name(val_proto);
2512
+ upb_value v = upb_value_constptr(val);
2513
+
2514
+ val->parent = e; /* Must happen prior to symtab_add(). */
2515
+ val->full_name = makefullname(ctx, prefix, name);
2516
+ val->number = google_protobuf_EnumValueDescriptorProto_number(val_proto);
2517
+ symtab_add(ctx, val->full_name, pack_def(val, UPB_DEFTYPE_ENUMVAL));
2518
+
2519
+ SET_OPTIONS(val->opts, EnumValueDescriptorProto, EnumValueOptions, val_proto);
2520
+
2521
+ if (i == 0 && e->file->syntax == kUpb_Syntax_Proto3 && val->number != 0) {
2522
+ symtab_errf(ctx, "for proto3, the first enum value must be zero (%s)",
2523
+ e->full_name);
2524
+ }
2525
+
2526
+ CHK_OOM(upb_strtable_insert(&e->ntoi, name.data, name.size, v, ctx->arena));
2527
+
2528
+ // Multiple enumerators can have the same number, first one wins.
2529
+ if (!upb_inttable_lookup(&e->iton, val->number, NULL)) {
2530
+ CHK_OOM(upb_inttable_insert(&e->iton, val->number, v, ctx->arena));
2531
+ }
2532
+ }
2533
+
2534
+ static void create_enumdef(
2535
+ symtab_addctx* ctx, const char* prefix,
2536
+ const google_protobuf_EnumDescriptorProto* enum_proto,
2537
+ const upb_MessageDef* containing_type, const upb_EnumDef* _e) {
2538
+ upb_EnumDef* e = (upb_EnumDef*)_e;
2539
+ ;
2540
+ const google_protobuf_EnumValueDescriptorProto* const* values;
2541
+ upb_StringView name;
2542
+ size_t i, n;
2543
+
2544
+ e->file = ctx->file; /* Must happen prior to symtab_add() */
2545
+ e->containing_type = containing_type;
2546
+
2547
+ name = google_protobuf_EnumDescriptorProto_name(enum_proto);
2548
+ check_ident(ctx, name, false);
2549
+
2550
+ e->full_name = makefullname(ctx, prefix, name);
2551
+ symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM));
2552
+
2553
+ values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n);
2554
+ CHK_OOM(upb_strtable_init(&e->ntoi, n, ctx->arena));
2555
+ CHK_OOM(upb_inttable_init(&e->iton, ctx->arena));
2556
+
2557
+ e->defaultval = 0;
2558
+ e->value_count = n;
2559
+ e->values = symtab_alloc(ctx, sizeof(*e->values) * n);
2560
+
2561
+ if (n == 0) {
2562
+ symtab_errf(ctx, "enums must contain at least one value (%s)",
2563
+ e->full_name);
2564
+ }
2565
+
2566
+ SET_OPTIONS(e->opts, EnumDescriptorProto, EnumOptions, enum_proto);
2567
+
2568
+ for (i = 0; i < n; i++) {
2569
+ create_enumvaldef(ctx, prefix, values[i], e, i);
2570
+ }
2571
+
2572
+ upb_inttable_compact(&e->iton, ctx->arena);
2573
+
2574
+ if (e->file->syntax == kUpb_Syntax_Proto2) {
2575
+ if (ctx->layout) {
2576
+ UPB_ASSERT(ctx->enum_count < ctx->layout->enum_count);
2577
+ e->layout = ctx->layout->enums[ctx->enum_count++];
2578
+ UPB_ASSERT(upb_inttable_count(&e->iton) ==
2579
+ e->layout->value_count + count_bits_debug(e->layout->mask));
2580
+ } else {
2581
+ e->layout = create_enumlayout(ctx, e);
2582
+ }
2583
+ } else {
2584
+ e->layout = NULL;
2585
+ }
2586
+ }
2587
+
2588
+ static void msgdef_create_nested(
2589
+ symtab_addctx* ctx, const google_protobuf_DescriptorProto* msg_proto,
2590
+ upb_MessageDef* m);
2591
+
2592
+ static void create_msgdef(symtab_addctx* ctx, const char* prefix,
2593
+ const google_protobuf_DescriptorProto* msg_proto,
2594
+ const upb_MessageDef* containing_type,
2595
+ const upb_MessageDef* _m) {
2596
+ upb_MessageDef* m = (upb_MessageDef*)_m;
2597
+ const google_protobuf_OneofDescriptorProto* const* oneofs;
2598
+ const google_protobuf_FieldDescriptorProto* const* fields;
2599
+ const google_protobuf_DescriptorProto_ExtensionRange* const* ext_ranges;
2600
+ size_t i, n_oneof, n_field, n_ext_range;
2601
+ upb_StringView name;
2602
+
2603
+ m->file = ctx->file; /* Must happen prior to symtab_add(). */
2604
+ m->containing_type = containing_type;
2605
+
2606
+ name = google_protobuf_DescriptorProto_name(msg_proto);
2607
+ check_ident(ctx, name, false);
2608
+
2609
+ m->full_name = makefullname(ctx, prefix, name);
2610
+ symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG));
2611
+
2612
+ oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n_oneof);
2613
+ fields = google_protobuf_DescriptorProto_field(msg_proto, &n_field);
2614
+ ext_ranges =
2615
+ google_protobuf_DescriptorProto_extension_range(msg_proto, &n_ext_range);
2616
+
2617
+ CHK_OOM(upb_inttable_init(&m->itof, ctx->arena));
2618
+ CHK_OOM(upb_strtable_init(&m->ntof, n_oneof + n_field, ctx->arena));
2619
+
2620
+ if (ctx->layout) {
2621
+ /* create_fielddef() below depends on this being set. */
2622
+ UPB_ASSERT(ctx->msg_count < ctx->layout->msg_count);
2623
+ m->layout = ctx->layout->msgs[ctx->msg_count++];
2624
+ UPB_ASSERT(n_field == m->layout->field_count);
2625
+ } else {
2626
+ /* Allocate now (to allow cross-linking), populate later. */
2627
+ m->layout =
2628
+ symtab_alloc(ctx, sizeof(*m->layout) + sizeof(_upb_FastTable_Entry));
2629
+ }
2630
+
2631
+ SET_OPTIONS(m->opts, DescriptorProto, MessageOptions, msg_proto);
2632
+
2633
+ m->oneof_count = n_oneof;
2634
+ m->oneofs = symtab_alloc(ctx, sizeof(*m->oneofs) * n_oneof);
2635
+ for (i = 0; i < n_oneof; i++) {
2636
+ create_oneofdef(ctx, m, oneofs[i], &m->oneofs[i]);
2637
+ }
2638
+
2639
+ m->field_count = n_field;
2640
+ m->fields = symtab_alloc(ctx, sizeof(*m->fields) * n_field);
2641
+ for (i = 0; i < n_field; i++) {
2642
+ create_fielddef(ctx, m->full_name, m, fields[i], &m->fields[i],
2643
+ /* is_extension= */ false);
2644
+ }
2645
+
2646
+ m->ext_range_count = n_ext_range;
2647
+ m->ext_ranges = symtab_alloc(ctx, sizeof(*m->ext_ranges) * n_ext_range);
2648
+ for (i = 0; i < n_ext_range; i++) {
2649
+ const google_protobuf_DescriptorProto_ExtensionRange* r = ext_ranges[i];
2650
+ upb_ExtensionRange* r_def = (upb_ExtensionRange*)&m->ext_ranges[i];
2651
+ int32_t start = google_protobuf_DescriptorProto_ExtensionRange_start(r);
2652
+ int32_t end = google_protobuf_DescriptorProto_ExtensionRange_end(r);
2653
+ int32_t max =
2654
+ google_protobuf_MessageOptions_message_set_wire_format(m->opts)
2655
+ ? INT32_MAX
2656
+ : kUpb_MaxFieldNumber + 1;
2657
+
2658
+ // A full validation would also check that each range is disjoint, and that
2659
+ // none of the fields overlap with the extension ranges, but we are just
2660
+ // sanity checking here.
2661
+ if (start < 1 || end <= start || end > max) {
2662
+ symtab_errf(ctx, "Extension range (%d, %d) is invalid, message=%s\n",
2663
+ (int)start, (int)end, m->full_name);
2664
+ }
2665
+
2666
+ r_def->start = start;
2667
+ r_def->end = end;
2668
+ SET_OPTIONS(r_def->opts, DescriptorProto_ExtensionRange,
2669
+ ExtensionRangeOptions, r);
2670
+ }
2671
+
2672
+ finalize_oneofs(ctx, m);
2673
+ assign_msg_wellknowntype(m);
2674
+ upb_inttable_compact(&m->itof, ctx->arena);
2675
+ msgdef_create_nested(ctx, msg_proto, m);
2676
+ }
2677
+
2678
+ static void msgdef_create_nested(
2679
+ symtab_addctx* ctx, const google_protobuf_DescriptorProto* msg_proto,
2680
+ upb_MessageDef* m) {
2681
+ size_t n;
2682
+
2683
+ const google_protobuf_EnumDescriptorProto* const* enums =
2684
+ google_protobuf_DescriptorProto_enum_type(msg_proto, &n);
2685
+ m->nested_enum_count = n;
2686
+ m->nested_enums = symtab_alloc(ctx, sizeof(*m->nested_enums) * n);
2687
+ for (size_t i = 0; i < n; i++) {
2688
+ m->nested_enum_count = i + 1;
2689
+ create_enumdef(ctx, m->full_name, enums[i], m, &m->nested_enums[i]);
2690
+ }
2691
+
2692
+ const google_protobuf_FieldDescriptorProto* const* exts =
2693
+ google_protobuf_DescriptorProto_extension(msg_proto, &n);
2694
+ m->nested_ext_count = n;
2695
+ m->nested_exts = symtab_alloc(ctx, sizeof(*m->nested_exts) * n);
2696
+ for (size_t i = 0; i < n; i++) {
2697
+ create_fielddef(ctx, m->full_name, m, exts[i], &m->nested_exts[i],
2698
+ /* is_extension= */ true);
2699
+ ((upb_FieldDef*)&m->nested_exts[i])->index_ = i;
2700
+ }
2701
+
2702
+ const google_protobuf_DescriptorProto* const* msgs =
2703
+ google_protobuf_DescriptorProto_nested_type(msg_proto, &n);
2704
+ m->nested_msg_count = n;
2705
+ m->nested_msgs = symtab_alloc(ctx, sizeof(*m->nested_msgs) * n);
2706
+ for (size_t i = 0; i < n; i++) {
2707
+ create_msgdef(ctx, m->full_name, msgs[i], m, &m->nested_msgs[i]);
2708
+ }
2709
+ }
2710
+
2711
+ static void resolve_subdef(symtab_addctx* ctx, const char* prefix,
2712
+ upb_FieldDef* f) {
2713
+ const google_protobuf_FieldDescriptorProto* field_proto = f->sub.unresolved;
2714
+ upb_StringView name =
2715
+ google_protobuf_FieldDescriptorProto_type_name(field_proto);
2716
+ bool has_name =
2717
+ google_protobuf_FieldDescriptorProto_has_type_name(field_proto);
2718
+ switch ((int)f->type_) {
2719
+ case FIELD_TYPE_UNSPECIFIED: {
2720
+ // Type was not specified and must be inferred.
2721
+ UPB_ASSERT(has_name);
2722
+ upb_deftype_t type;
2723
+ const void* def =
2724
+ symtab_resolveany(ctx, f->full_name, prefix, name, &type);
2725
+ switch (type) {
2726
+ case UPB_DEFTYPE_ENUM:
2727
+ f->sub.enumdef = def;
2728
+ f->type_ = kUpb_FieldType_Enum;
2729
+ break;
2730
+ case UPB_DEFTYPE_MSG:
2731
+ f->sub.msgdef = def;
2732
+ f->type_ = kUpb_FieldType_Message; // It appears there is no way of
2733
+ // this being a group.
2734
+ break;
2735
+ default:
2736
+ symtab_errf(ctx, "Couldn't resolve type name for field %s",
2737
+ f->full_name);
2738
+ }
2739
+ }
2740
+ case kUpb_FieldType_Message:
2741
+ case kUpb_FieldType_Group:
2742
+ UPB_ASSERT(has_name);
2743
+ f->sub.msgdef =
2744
+ symtab_resolve(ctx, f->full_name, prefix, name, UPB_DEFTYPE_MSG);
2745
+ break;
2746
+ case kUpb_FieldType_Enum:
2747
+ UPB_ASSERT(has_name);
2748
+ f->sub.enumdef =
2749
+ symtab_resolve(ctx, f->full_name, prefix, name, UPB_DEFTYPE_ENUM);
2750
+ break;
2751
+ default:
2752
+ // No resolution necessary.
2753
+ break;
2754
+ }
2755
+ }
2756
+
2757
+ static void resolve_extension(
2758
+ symtab_addctx* ctx, const char* prefix, upb_FieldDef* f,
2759
+ const google_protobuf_FieldDescriptorProto* field_proto) {
2760
+ if (!google_protobuf_FieldDescriptorProto_has_extendee(field_proto)) {
2761
+ symtab_errf(ctx, "extension for field '%s' had no extendee", f->full_name);
2762
+ }
2763
+
2764
+ upb_StringView name =
2765
+ google_protobuf_FieldDescriptorProto_extendee(field_proto);
2766
+ const upb_MessageDef* m =
2767
+ symtab_resolve(ctx, f->full_name, prefix, name, UPB_DEFTYPE_MSG);
2768
+ f->msgdef = m;
2769
+
2770
+ bool found = false;
2771
+
2772
+ for (int i = 0, n = m->ext_range_count; i < n; i++) {
2773
+ const upb_ExtensionRange* r = &m->ext_ranges[i];
2774
+ if (r->start <= f->number_ && f->number_ < r->end) {
2775
+ found = true;
2776
+ break;
2777
+ }
2778
+ }
2779
+
2780
+ if (!found) {
2781
+ symtab_errf(ctx,
2782
+ "field number %u in extension %s has no extension range in "
2783
+ "message %s",
2784
+ (unsigned)f->number_, f->full_name, f->msgdef->full_name);
2785
+ }
2786
+
2787
+ const upb_MiniTable_Extension* ext = ctx->file->ext_layouts[f->layout_index];
2788
+ if (ctx->layout) {
2789
+ UPB_ASSERT(upb_FieldDef_Number(f) == ext->field.number);
2790
+ } else {
2791
+ upb_MiniTable_Extension* mut_ext = (upb_MiniTable_Extension*)ext;
2792
+ fill_fieldlayout(&mut_ext->field, f);
2793
+ mut_ext->field.presence = 0;
2794
+ mut_ext->field.offset = 0;
2795
+ mut_ext->field.submsg_index = 0;
2796
+ mut_ext->extendee = f->msgdef->layout;
2797
+ mut_ext->sub.submsg = f->sub.msgdef->layout;
2798
+ }
2799
+
2800
+ CHK_OOM(upb_inttable_insert(&ctx->symtab->exts, (uintptr_t)ext,
2801
+ upb_value_constptr(f), ctx->arena));
2802
+ }
2803
+
2804
+ static void resolve_default(
2805
+ symtab_addctx* ctx, upb_FieldDef* f,
2806
+ const google_protobuf_FieldDescriptorProto* field_proto) {
2807
+ // Have to delay resolving of the default value until now because of the enum
2808
+ // case, since enum defaults are specified with a label.
2809
+ if (google_protobuf_FieldDescriptorProto_has_default_value(field_proto)) {
2810
+ upb_StringView defaultval =
2811
+ google_protobuf_FieldDescriptorProto_default_value(field_proto);
2812
+
2813
+ if (f->file->syntax == kUpb_Syntax_Proto3) {
2814
+ symtab_errf(ctx, "proto3 fields cannot have explicit defaults (%s)",
2815
+ f->full_name);
2816
+ }
2817
+
2818
+ if (upb_FieldDef_IsSubMessage(f)) {
2819
+ symtab_errf(ctx, "message fields cannot have explicit defaults (%s)",
2820
+ f->full_name);
2821
+ }
2822
+
2823
+ parse_default(ctx, defaultval.data, defaultval.size, f);
2824
+ f->has_default = true;
2825
+ } else {
2826
+ set_default_default(ctx, f);
2827
+ f->has_default = false;
2828
+ }
2829
+ }
2830
+
2831
+ static void resolve_fielddef(symtab_addctx* ctx, const char* prefix,
2832
+ upb_FieldDef* f) {
2833
+ // We have to stash this away since resolve_subdef() may overwrite it.
2834
+ const google_protobuf_FieldDescriptorProto* field_proto = f->sub.unresolved;
2835
+
2836
+ resolve_subdef(ctx, prefix, f);
2837
+ resolve_default(ctx, f, field_proto);
2838
+
2839
+ if (f->is_extension_) {
2840
+ resolve_extension(ctx, prefix, f, field_proto);
2841
+ }
2842
+ }
2843
+
2844
+ static void resolve_msgdef(symtab_addctx* ctx, upb_MessageDef* m) {
2845
+ for (int i = 0; i < m->field_count; i++) {
2846
+ resolve_fielddef(ctx, m->full_name, (upb_FieldDef*)&m->fields[i]);
2847
+ }
2848
+
2849
+ m->in_message_set = false;
2850
+ for (int i = 0; i < m->nested_ext_count; i++) {
2851
+ upb_FieldDef* ext = (upb_FieldDef*)&m->nested_exts[i];
2852
+ resolve_fielddef(ctx, m->full_name, ext);
2853
+ if (ext->type_ == kUpb_FieldType_Message &&
2854
+ ext->label_ == kUpb_Label_Optional && ext->sub.msgdef == m &&
2855
+ google_protobuf_MessageOptions_message_set_wire_format(
2856
+ ext->msgdef->opts)) {
2857
+ m->in_message_set = true;
2858
+ }
2859
+ }
2860
+
2861
+ if (!ctx->layout) make_layout(ctx, m);
2862
+
2863
+ for (int i = 0; i < m->nested_msg_count; i++) {
2864
+ resolve_msgdef(ctx, (upb_MessageDef*)&m->nested_msgs[i]);
2865
+ }
2866
+ }
2867
+
2868
+ static int count_exts_in_msg(const google_protobuf_DescriptorProto* msg_proto) {
2869
+ size_t n;
2870
+ google_protobuf_DescriptorProto_extension(msg_proto, &n);
2871
+ int ext_count = n;
2872
+
2873
+ const google_protobuf_DescriptorProto* const* nested_msgs =
2874
+ google_protobuf_DescriptorProto_nested_type(msg_proto, &n);
2875
+ for (size_t i = 0; i < n; i++) {
2876
+ ext_count += count_exts_in_msg(nested_msgs[i]);
2877
+ }
2878
+
2879
+ return ext_count;
2880
+ }
2881
+
2882
+ static void build_filedef(
2883
+ symtab_addctx* ctx, upb_FileDef* file,
2884
+ const google_protobuf_FileDescriptorProto* file_proto) {
2885
+ const google_protobuf_DescriptorProto* const* msgs;
2886
+ const google_protobuf_EnumDescriptorProto* const* enums;
2887
+ const google_protobuf_FieldDescriptorProto* const* exts;
2888
+ const google_protobuf_ServiceDescriptorProto* const* services;
2889
+ const upb_StringView* strs;
2890
+ const int32_t* public_deps;
2891
+ const int32_t* weak_deps;
2892
+ size_t i, n;
2893
+
2894
+ file->symtab = ctx->symtab;
2895
+
2896
+ /* Count all extensions in the file, to build a flat array of layouts. */
2897
+ google_protobuf_FileDescriptorProto_extension(file_proto, &n);
2898
+ int ext_count = n;
2899
+ msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n);
2900
+ for (int i = 0; i < n; i++) {
2901
+ ext_count += count_exts_in_msg(msgs[i]);
2902
+ }
2903
+ file->ext_count = ext_count;
2904
+
2905
+ if (ctx->layout) {
2906
+ /* We are using the ext layouts that were passed in. */
2907
+ file->ext_layouts = ctx->layout->exts;
2908
+ if (ctx->layout->ext_count != file->ext_count) {
2909
+ symtab_errf(ctx, "Extension count did not match layout (%d vs %d)",
2910
+ ctx->layout->ext_count, file->ext_count);
2911
+ }
2912
+ } else {
2913
+ /* We are building ext layouts from scratch. */
2914
+ file->ext_layouts =
2915
+ symtab_alloc(ctx, sizeof(*file->ext_layouts) * file->ext_count);
2916
+ upb_MiniTable_Extension* ext =
2917
+ symtab_alloc(ctx, sizeof(*ext) * file->ext_count);
2918
+ for (int i = 0; i < file->ext_count; i++) {
2919
+ file->ext_layouts[i] = &ext[i];
2920
+ }
2921
+ }
2922
+
2923
+ if (!google_protobuf_FileDescriptorProto_has_name(file_proto)) {
2924
+ symtab_errf(ctx, "File has no name");
2925
+ }
2926
+
2927
+ file->name =
2928
+ strviewdup(ctx, google_protobuf_FileDescriptorProto_name(file_proto));
2929
+
2930
+ if (google_protobuf_FileDescriptorProto_has_package(file_proto)) {
2931
+ upb_StringView package =
2932
+ google_protobuf_FileDescriptorProto_package(file_proto);
2933
+ check_ident(ctx, package, true);
2934
+ file->package = strviewdup(ctx, package);
2935
+ } else {
2936
+ file->package = NULL;
2937
+ }
2938
+
2939
+ if (google_protobuf_FileDescriptorProto_has_syntax(file_proto)) {
2940
+ upb_StringView syntax =
2941
+ google_protobuf_FileDescriptorProto_syntax(file_proto);
2942
+
2943
+ if (streql_view(syntax, "proto2")) {
2944
+ file->syntax = kUpb_Syntax_Proto2;
2945
+ } else if (streql_view(syntax, "proto3")) {
2946
+ file->syntax = kUpb_Syntax_Proto3;
2947
+ } else {
2948
+ symtab_errf(ctx, "Invalid syntax '" UPB_STRINGVIEW_FORMAT "'",
2949
+ UPB_STRINGVIEW_ARGS(syntax));
2950
+ }
2951
+ } else {
2952
+ file->syntax = kUpb_Syntax_Proto2;
2953
+ }
2954
+
2955
+ /* Read options. */
2956
+ SET_OPTIONS(file->opts, FileDescriptorProto, FileOptions, file_proto);
2957
+
2958
+ /* Verify dependencies. */
2959
+ strs = google_protobuf_FileDescriptorProto_dependency(file_proto, &n);
2960
+ file->dep_count = n;
2961
+ file->deps = symtab_alloc(ctx, sizeof(*file->deps) * n);
2962
+
2963
+ for (i = 0; i < n; i++) {
2964
+ upb_StringView str = strs[i];
2965
+ file->deps[i] =
2966
+ upb_DefPool_FindFileByNameWithSize(ctx->symtab, str.data, str.size);
2967
+ if (!file->deps[i]) {
2968
+ symtab_errf(ctx,
2969
+ "Depends on file '" UPB_STRINGVIEW_FORMAT
2970
+ "', but it has not been loaded",
2971
+ UPB_STRINGVIEW_ARGS(str));
2972
+ }
2973
+ }
2974
+
2975
+ public_deps =
2976
+ google_protobuf_FileDescriptorProto_public_dependency(file_proto, &n);
2977
+ file->public_dep_count = n;
2978
+ file->public_deps = symtab_alloc(ctx, sizeof(*file->public_deps) * n);
2979
+ int32_t* mutable_public_deps = (int32_t*)file->public_deps;
2980
+ for (i = 0; i < n; i++) {
2981
+ if (public_deps[i] >= file->dep_count) {
2982
+ symtab_errf(ctx, "public_dep %d is out of range", (int)public_deps[i]);
2983
+ }
2984
+ mutable_public_deps[i] = public_deps[i];
2985
+ }
2986
+
2987
+ weak_deps =
2988
+ google_protobuf_FileDescriptorProto_weak_dependency(file_proto, &n);
2989
+ file->weak_dep_count = n;
2990
+ file->weak_deps = symtab_alloc(ctx, sizeof(*file->weak_deps) * n);
2991
+ int32_t* mutable_weak_deps = (int32_t*)file->weak_deps;
2992
+ for (i = 0; i < n; i++) {
2993
+ if (weak_deps[i] >= file->dep_count) {
2994
+ symtab_errf(ctx, "weak_dep %d is out of range", (int)weak_deps[i]);
2995
+ }
2996
+ mutable_weak_deps[i] = weak_deps[i];
2997
+ }
2998
+
2999
+ /* Create enums. */
3000
+ enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n);
3001
+ file->top_lvl_enum_count = n;
3002
+ file->top_lvl_enums = symtab_alloc(ctx, sizeof(*file->top_lvl_enums) * n);
3003
+ for (i = 0; i < n; i++) {
3004
+ create_enumdef(ctx, file->package, enums[i], NULL, &file->top_lvl_enums[i]);
3005
+ }
3006
+
3007
+ /* Create extensions. */
3008
+ exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n);
3009
+ file->top_lvl_ext_count = n;
3010
+ file->top_lvl_exts = symtab_alloc(ctx, sizeof(*file->top_lvl_exts) * n);
3011
+ for (i = 0; i < n; i++) {
3012
+ create_fielddef(ctx, file->package, NULL, exts[i], &file->top_lvl_exts[i],
3013
+ /* is_extension= */ true);
3014
+ ((upb_FieldDef*)&file->top_lvl_exts[i])->index_ = i;
3015
+ }
3016
+
3017
+ /* Create messages. */
3018
+ msgs = google_protobuf_FileDescriptorProto_message_type(file_proto, &n);
3019
+ file->top_lvl_msg_count = n;
3020
+ file->top_lvl_msgs = symtab_alloc(ctx, sizeof(*file->top_lvl_msgs) * n);
3021
+ for (i = 0; i < n; i++) {
3022
+ create_msgdef(ctx, file->package, msgs[i], NULL, &file->top_lvl_msgs[i]);
3023
+ }
3024
+
3025
+ /* Create services. */
3026
+ services = google_protobuf_FileDescriptorProto_service(file_proto, &n);
3027
+ file->service_count = n;
3028
+ file->services = symtab_alloc(ctx, sizeof(*file->services) * n);
3029
+ for (i = 0; i < n; i++) {
3030
+ create_service(ctx, services[i], &file->services[i]);
3031
+ ((upb_ServiceDef*)&file->services[i])->index = i;
3032
+ }
3033
+
3034
+ /* Now that all names are in the table, build layouts and resolve refs. */
3035
+ for (i = 0; i < (size_t)file->top_lvl_ext_count; i++) {
3036
+ resolve_fielddef(ctx, file->package, (upb_FieldDef*)&file->top_lvl_exts[i]);
3037
+ }
3038
+
3039
+ for (i = 0; i < (size_t)file->top_lvl_msg_count; i++) {
3040
+ resolve_msgdef(ctx, (upb_MessageDef*)&file->top_lvl_msgs[i]);
3041
+ }
3042
+
3043
+ if (file->ext_count) {
3044
+ CHK_OOM(_upb_extreg_add(ctx->symtab->extreg, file->ext_layouts,
3045
+ file->ext_count));
3046
+ }
3047
+ }
3048
+
3049
+ static void remove_filedef(upb_DefPool* s, upb_FileDef* file) {
3050
+ intptr_t iter = UPB_INTTABLE_BEGIN;
3051
+ upb_StringView key;
3052
+ upb_value val;
3053
+ while (upb_strtable_next2(&s->syms, &key, &val, &iter)) {
3054
+ const upb_FileDef* f;
3055
+ switch (deftype(val)) {
3056
+ case UPB_DEFTYPE_EXT:
3057
+ f = upb_FieldDef_File(unpack_def(val, UPB_DEFTYPE_EXT));
3058
+ break;
3059
+ case UPB_DEFTYPE_MSG:
3060
+ f = upb_MessageDef_File(unpack_def(val, UPB_DEFTYPE_MSG));
3061
+ break;
3062
+ case UPB_DEFTYPE_ENUM:
3063
+ f = upb_EnumDef_File(unpack_def(val, UPB_DEFTYPE_ENUM));
3064
+ break;
3065
+ case UPB_DEFTYPE_ENUMVAL:
3066
+ f = upb_EnumDef_File(
3067
+ upb_EnumValueDef_Enum(unpack_def(val, UPB_DEFTYPE_ENUMVAL)));
3068
+ break;
3069
+ case UPB_DEFTYPE_SERVICE:
3070
+ f = upb_ServiceDef_File(unpack_def(val, UPB_DEFTYPE_SERVICE));
3071
+ break;
3072
+ default:
3073
+ UPB_UNREACHABLE();
3074
+ }
3075
+
3076
+ if (f == file) upb_strtable_removeiter(&s->syms, &iter);
3077
+ }
3078
+ }
3079
+
3080
+ static const upb_FileDef* _upb_DefPool_AddFile(
3081
+ upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto,
3082
+ const upb_MiniTable_File* layout, upb_Status* status) {
3083
+ symtab_addctx ctx;
3084
+ upb_StringView name = google_protobuf_FileDescriptorProto_name(file_proto);
3085
+ upb_value v;
3086
+
3087
+ if (upb_strtable_lookup2(&s->files, name.data, name.size, &v)) {
3088
+ if (unpack_def(v, UPB_DEFTYPE_FILE)) {
3089
+ upb_Status_SetErrorFormat(status, "duplicate file name (%.*s)",
3090
+ UPB_STRINGVIEW_ARGS(name));
3091
+ return NULL;
3092
+ }
3093
+ const upb_MiniTable_File* registered = unpack_def(v, UPB_DEFTYPE_LAYOUT);
3094
+ UPB_ASSERT(registered);
3095
+ if (layout && layout != registered) {
3096
+ upb_Status_SetErrorFormat(
3097
+ status, "tried to build with a different layout (filename=%.*s)",
3098
+ UPB_STRINGVIEW_ARGS(name));
3099
+ return NULL;
3100
+ }
3101
+ layout = registered;
3102
+ }
3103
+
3104
+ ctx.symtab = s;
3105
+ ctx.layout = layout;
3106
+ ctx.msg_count = 0;
3107
+ ctx.enum_count = 0;
3108
+ ctx.ext_count = 0;
3109
+ ctx.status = status;
3110
+ ctx.file = NULL;
3111
+ ctx.arena = upb_Arena_New();
3112
+ ctx.tmp_arena = upb_Arena_New();
3113
+
3114
+ if (!ctx.arena || !ctx.tmp_arena) {
3115
+ if (ctx.arena) upb_Arena_Free(ctx.arena);
3116
+ if (ctx.tmp_arena) upb_Arena_Free(ctx.tmp_arena);
3117
+ upb_Status_setoom(status);
3118
+ return NULL;
3119
+ }
3120
+
3121
+ if (UPB_UNLIKELY(UPB_SETJMP(ctx.err))) {
3122
+ UPB_ASSERT(!upb_Status_IsOk(status));
3123
+ if (ctx.file) {
3124
+ remove_filedef(s, ctx.file);
3125
+ ctx.file = NULL;
3126
+ }
3127
+ } else {
3128
+ ctx.file = symtab_alloc(&ctx, sizeof(*ctx.file));
3129
+ build_filedef(&ctx, ctx.file, file_proto);
3130
+ upb_strtable_insert(&s->files, name.data, name.size,
3131
+ pack_def(ctx.file, UPB_DEFTYPE_FILE), ctx.arena);
3132
+ UPB_ASSERT(upb_Status_IsOk(status));
3133
+ upb_Arena_Fuse(s->arena, ctx.arena);
3134
+ }
3135
+
3136
+ upb_Arena_Free(ctx.arena);
3137
+ upb_Arena_Free(ctx.tmp_arena);
3138
+ return ctx.file;
3139
+ }
3140
+
3141
+ const upb_FileDef* upb_DefPool_AddFile(
3142
+ upb_DefPool* s, const google_protobuf_FileDescriptorProto* file_proto,
3143
+ upb_Status* status) {
3144
+ return _upb_DefPool_AddFile(s, file_proto, NULL, status);
3145
+ }
3146
+
3147
+ /* Include here since we want most of this file to be stdio-free. */
3148
+ #include <stdio.h>
3149
+
3150
+ bool _upb_DefPool_LoadDefInitEx(upb_DefPool* s, const _upb_DefPool_Init* init,
3151
+ bool rebuild_minitable) {
3152
+ /* Since this function should never fail (it would indicate a bug in upb) we
3153
+ * print errors to stderr instead of returning error status to the user. */
3154
+ _upb_DefPool_Init** deps = init->deps;
3155
+ google_protobuf_FileDescriptorProto* file;
3156
+ upb_Arena* arena;
3157
+ upb_Status status;
3158
+
3159
+ upb_Status_Clear(&status);
3160
+
3161
+ if (upb_DefPool_FindFileByName(s, init->filename)) {
3162
+ return true;
3163
+ }
3164
+
3165
+ arena = upb_Arena_New();
3166
+
3167
+ for (; *deps; deps++) {
3168
+ if (!_upb_DefPool_LoadDefInitEx(s, *deps, rebuild_minitable)) goto err;
3169
+ }
3170
+
3171
+ file = google_protobuf_FileDescriptorProto_parse_ex(
3172
+ init->descriptor.data, init->descriptor.size, NULL,
3173
+ kUpb_DecodeOption_AliasString, arena);
3174
+ s->bytes_loaded += init->descriptor.size;
3175
+
3176
+ if (!file) {
3177
+ upb_Status_SetErrorFormat(
3178
+ &status,
3179
+ "Failed to parse compiled-in descriptor for file '%s'. This should "
3180
+ "never happen.",
3181
+ init->filename);
3182
+ goto err;
3183
+ }
3184
+
3185
+ const upb_MiniTable_File* mt = rebuild_minitable ? NULL : init->layout;
3186
+ if (!_upb_DefPool_AddFile(s, file, mt, &status)) {
3187
+ goto err;
3188
+ }
3189
+
3190
+ upb_Arena_Free(arena);
3191
+ return true;
3192
+
3193
+ err:
3194
+ fprintf(stderr,
3195
+ "Error loading compiled-in descriptor for file '%s' (this should "
3196
+ "never happen): %s\n",
3197
+ init->filename, upb_Status_ErrorMessage(&status));
3198
+ upb_Arena_Free(arena);
3199
+ return false;
3200
+ }
3201
+
3202
+ size_t _upb_DefPool_BytesLoaded(const upb_DefPool* s) {
3203
+ return s->bytes_loaded;
3204
+ }
3205
+
3206
+ upb_Arena* _upb_DefPool_Arena(const upb_DefPool* s) { return s->arena; }
3207
+
3208
+ const upb_FieldDef* _upb_DefPool_FindExtensionByMiniTable(
3209
+ const upb_DefPool* s, const upb_MiniTable_Extension* ext) {
3210
+ upb_value v;
3211
+ bool ok = upb_inttable_lookup(&s->exts, (uintptr_t)ext, &v);
3212
+ UPB_ASSERT(ok);
3213
+ return upb_value_getconstptr(v);
3214
+ }
3215
+
3216
+ const upb_FieldDef* upb_DefPool_FindExtensionByNumber(const upb_DefPool* s,
3217
+ const upb_MessageDef* m,
3218
+ int32_t fieldnum) {
3219
+ const upb_MiniTable* l = upb_MessageDef_MiniTable(m);
3220
+ const upb_MiniTable_Extension* ext = _upb_extreg_get(s->extreg, l, fieldnum);
3221
+ return ext ? _upb_DefPool_FindExtensionByMiniTable(s, ext) : NULL;
3222
+ }
3223
+
3224
+ bool _upb_DefPool_registerlayout(upb_DefPool* s, const char* filename,
3225
+ const upb_MiniTable_File* file) {
3226
+ if (upb_DefPool_FindFileByName(s, filename)) return false;
3227
+ upb_value v = pack_def(file, UPB_DEFTYPE_LAYOUT);
3228
+ return upb_strtable_insert(&s->files, filename, strlen(filename), v,
3229
+ s->arena);
3230
+ }
3231
+
3232
+ const upb_ExtensionRegistry* upb_DefPool_ExtensionRegistry(
3233
+ const upb_DefPool* s) {
3234
+ return s->extreg;
3235
+ }
3236
+
3237
+ const upb_FieldDef** upb_DefPool_GetAllExtensions(const upb_DefPool* s,
3238
+ const upb_MessageDef* m,
3239
+ size_t* count) {
3240
+ size_t n = 0;
3241
+ intptr_t iter = UPB_INTTABLE_BEGIN;
3242
+ uintptr_t key;
3243
+ upb_value val;
3244
+ // This is O(all exts) instead of O(exts for m). If we need this to be
3245
+ // efficient we may need to make extreg into a two-level table, or have a
3246
+ // second per-message index.
3247
+ while (upb_inttable_next2(&s->exts, &key, &val, &iter)) {
3248
+ const upb_FieldDef* f = upb_value_getconstptr(val);
3249
+ if (upb_FieldDef_ContainingType(f) == m) n++;
3250
+ }
3251
+ const upb_FieldDef** exts = malloc(n * sizeof(*exts));
3252
+ iter = UPB_INTTABLE_BEGIN;
3253
+ size_t i = 0;
3254
+ while (upb_inttable_next2(&s->exts, &key, &val, &iter)) {
3255
+ const upb_FieldDef* f = upb_value_getconstptr(val);
3256
+ if (upb_FieldDef_ContainingType(f) == m) exts[i++] = f;
3257
+ }
3258
+ *count = n;
3259
+ return exts;
3260
+ }
3261
+
3262
+ #undef CHK_OOM