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,143 @@
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/util/def_to_proto.h"
29
+
30
+ #include "gmock/gmock.h"
31
+ #include "google/protobuf/descriptor.pb.h"
32
+ #include "google/protobuf/descriptor.upbdefs.h"
33
+ #include "google/protobuf/dynamic_message.h"
34
+ #include "google/protobuf/util/message_differencer.h"
35
+ #include "gtest/gtest.h"
36
+ #include "upb/def.hpp"
37
+ #include "upb/upb.hpp"
38
+ #include "upb/util/def_to_proto_test.upbdefs.h"
39
+
40
+ // Loads and retrieves a descriptor for `msgdef` into the given `pool`.
41
+ const google::protobuf::Descriptor* AddMessageDescriptor(
42
+ upb::MessageDefPtr msgdef, google::protobuf::DescriptorPool* pool) {
43
+ upb::Arena tmp_arena;
44
+ upb::FileDefPtr file = msgdef.file();
45
+ google_protobuf_FileDescriptorProto* upb_proto =
46
+ upb_FileDef_ToProto(file.ptr(), tmp_arena.ptr());
47
+ size_t size;
48
+ const char* buf = google_protobuf_FileDescriptorProto_serialize(
49
+ upb_proto, tmp_arena.ptr(), &size);
50
+ google::protobuf::FileDescriptorProto google_proto;
51
+ google_proto.ParseFromArray(buf, size);
52
+ const google::protobuf::FileDescriptor* file_desc =
53
+ pool->BuildFile(google_proto);
54
+ EXPECT_TRUE(file_desc != nullptr);
55
+ return pool->FindMessageTypeByName(msgdef.full_name());
56
+ }
57
+
58
+ // Converts a upb `msg` (with type `msgdef`) into a protobuf Message object from
59
+ // the given factory and descriptor.
60
+ std::unique_ptr<google::protobuf::Message> ToProto(
61
+ const upb_Message* msg, const upb_MessageDef* msgdef,
62
+ const google::protobuf::Descriptor* desc,
63
+ google::protobuf::MessageFactory* factory) {
64
+ upb::Arena arena;
65
+ EXPECT_TRUE(desc != nullptr);
66
+ std::unique_ptr<google::protobuf::Message> google_msg(
67
+ factory->GetPrototype(desc)->New());
68
+ size_t size;
69
+ const char* buf =
70
+ upb_Encode(msg, upb_MessageDef_MiniTable(msgdef), 0, arena.ptr(), &size);
71
+ google_msg->ParseFromArray(buf, size);
72
+ return google_msg;
73
+ }
74
+
75
+ // A gtest matcher that verifies that a proto is equal to `proto`. Both `proto`
76
+ // and `arg` must be messages of type `msgdef_func` (a .upbdefs.h function that
77
+ // loads a known msgdef into the given symtab).
78
+ MATCHER_P2(EqualsUpbProto, proto, msgdef_func,
79
+ negation ? "are not equal" : "are equal") {
80
+ upb::SymbolTable symtab;
81
+ google::protobuf::DescriptorPool pool;
82
+ google::protobuf::DynamicMessageFactory factory;
83
+ upb::MessageDefPtr msgdef(msgdef_func(symtab.ptr()));
84
+ EXPECT_TRUE(msgdef.ptr() != nullptr);
85
+ const google::protobuf::Descriptor* desc =
86
+ AddMessageDescriptor(msgdef, &pool);
87
+ EXPECT_TRUE(desc != nullptr);
88
+ std::unique_ptr<google::protobuf::Message> m1(
89
+ ToProto(proto, msgdef.ptr(), desc, &factory));
90
+ std::unique_ptr<google::protobuf::Message> m2(
91
+ ToProto(arg, msgdef.ptr(), desc, &factory));
92
+ std::string differences;
93
+ google::protobuf::util::MessageDifferencer differencer;
94
+ differencer.ReportDifferencesToString(&differences);
95
+ bool eq = differencer.Compare(*m2, *m1);
96
+ if (!eq) {
97
+ *result_listener << differences;
98
+ }
99
+ return eq;
100
+ }
101
+
102
+ // Verifies that the given upb FileDef can be converted to a proto that matches
103
+ // `proto`.
104
+ void CheckFile(const upb::FileDefPtr file,
105
+ const google_protobuf_FileDescriptorProto* proto) {
106
+ upb::Arena arena;
107
+ google_protobuf_FileDescriptorProto* proto2 =
108
+ upb_FileDef_ToProto(file.ptr(), arena.ptr());
109
+ ASSERT_THAT(
110
+ proto,
111
+ EqualsUpbProto(proto2, google_protobuf_FileDescriptorProto_getmsgdef));
112
+ }
113
+
114
+ // Verifies that upb/util/def_to_proto_test.proto can round-trip:
115
+ // serialized descriptor -> upb def -> serialized descriptor
116
+ TEST(DefToProto, Test) {
117
+ upb::Arena arena;
118
+ upb::SymbolTable symtab;
119
+ upb_StringView test_file_desc =
120
+ upb_util_def_to_proto_test_proto_upbdefinit.descriptor;
121
+ const auto* file_desc = google_protobuf_FileDescriptorProto_parse(
122
+ test_file_desc.data, test_file_desc.size, arena.ptr());
123
+
124
+ upb::MessageDefPtr msgdef(pkg_Message_getmsgdef(symtab.ptr()));
125
+ upb::FileDefPtr file = msgdef.file();
126
+ CheckFile(file, file_desc);
127
+ }
128
+
129
+ // Like the previous test, but uses a message layout built at runtime.
130
+ TEST(DefToProto, TestRuntimeReflection) {
131
+ upb::Arena arena;
132
+ upb::SymbolTable symtab;
133
+ upb_StringView test_file_desc =
134
+ upb_util_def_to_proto_test_proto_upbdefinit.descriptor;
135
+ const auto* file_desc = google_protobuf_FileDescriptorProto_parse(
136
+ test_file_desc.data, test_file_desc.size, arena.ptr());
137
+
138
+ _upb_DefPool_LoadDefInitEx(
139
+ symtab.ptr(), &upb_util_def_to_proto_test_proto_upbdefinit, true);
140
+ upb::FileDefPtr file = symtab.FindFileByName(
141
+ upb_util_def_to_proto_test_proto_upbdefinit.filename);
142
+ CheckFile(file, file_desc);
143
+ }
@@ -0,0 +1,119 @@
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
+ syntax = "proto2";
29
+
30
+ package pkg;
31
+
32
+ import public "upb/util/def_to_proto_public_import_test.proto";
33
+
34
+ import "upb/util/def_to_proto_regular_import_test.proto";
35
+
36
+ option optimize_for = CODE_SIZE;
37
+ option go_package = "foo_go_package";
38
+ option java_package = "bar_java_package";
39
+ option java_outer_classname = "baz_java_outer_classname";
40
+ option csharp_namespace = "quux_csharp_namespace";
41
+ option objc_class_prefix = "the_objc_prefix";
42
+ option cc_enable_arenas = true;
43
+
44
+ message Message {
45
+ optional int32 a = 1 [default = 3];
46
+ oneof foo {
47
+ string oneof_string = 2 [default = "abc\n"];
48
+ string oneof_bool = 3 [default = "true"];
49
+ bytes oneof_bytes = 4 [default = "abc\xef\xfe"];
50
+ }
51
+ optional pkg.RegularImportMessage regular_import_message = 6;
52
+ optional pkg.PublicImportMessage public_import_message = 7;
53
+ optional pkg.Proto3Enum proto3_enum = 8;
54
+ extensions 1000 to max;
55
+ extend Message {
56
+ optional int32 ext = 1000;
57
+ }
58
+
59
+ message NestedMessage {}
60
+ message NestedEnum {}
61
+
62
+ // TODO: support reserved ranges in defs.
63
+ // (At the moment they are ignored and will not round-trip through defs).
64
+ // reserved 4, 6 to 8;
65
+ }
66
+
67
+ enum Enum {
68
+ ZERO = 0;
69
+ ONE = 1;
70
+ NEGATIVE_ONE = -1;
71
+ }
72
+
73
+ enum EnumUpper32Value {
74
+ UPPER32_VALUE = 40;
75
+ }
76
+
77
+ enum HasDuplicateValues {
78
+ option allow_alias = true;
79
+
80
+ A = 0;
81
+ B = 1;
82
+ C = 120;
83
+ D = 130;
84
+
85
+ G = 120;
86
+ F = 1;
87
+ E = 0;
88
+ H = 121;
89
+ I = 121;
90
+ J = 121;
91
+ K = 121;
92
+ }
93
+
94
+ service Service {
95
+ rpc Bar(Message) returns (Message);
96
+ }
97
+
98
+ extend Message {
99
+ optional int32 ext = 1001;
100
+ }
101
+
102
+ enum Has31 {
103
+ VALUE_31 = 31;
104
+ }
105
+
106
+ message PretendMessageSet {
107
+ option message_set_wire_format = true;
108
+
109
+ // Since this is message_set_wire_format, "max" here means INT32_MAX.
110
+ // (For normal messages "max" would mean 2**29 - 1).
111
+ extensions 4 to max;
112
+ }
113
+
114
+ message MessageSetItem {
115
+ extend PretendMessageSet {
116
+ // Since max is exclusive, this is INT32_MAX-1, not INT32_MAX.
117
+ optional MessageSetItem message_set_extension = 2147483646;
118
+ }
119
+ }
@@ -0,0 +1,28 @@
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
+ syntax = "proto3";
@@ -0,0 +1,28 @@
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
+ syntax = "proto3";
@@ -0,0 +1,311 @@
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/util/required_fields.h"
29
+
30
+ #include <inttypes.h>
31
+ #include <setjmp.h>
32
+ #include <stdarg.h>
33
+ #include <stdio.h>
34
+
35
+ #include "upb/reflection.h"
36
+
37
+ // Must be last.
38
+ #include "upb/port_def.inc"
39
+
40
+ ////////////////////////////////////////////////////////////////////////////////
41
+ // upb_FieldPath_ToText()
42
+ ////////////////////////////////////////////////////////////////////////////////
43
+
44
+ typedef struct {
45
+ char* buf;
46
+ char* ptr;
47
+ char* end;
48
+ size_t overflow;
49
+ } upb_PrintfAppender;
50
+
51
+ UPB_PRINTF(2, 3)
52
+ static void upb_FieldPath_Printf(upb_PrintfAppender* a, const char* fmt, ...) {
53
+ size_t n;
54
+ size_t have = a->end - a->ptr;
55
+ va_list args;
56
+
57
+ va_start(args, fmt);
58
+ n = vsnprintf(a->ptr, have, fmt, args);
59
+ va_end(args);
60
+
61
+ if (UPB_LIKELY(have > n)) {
62
+ // We can't end up here if the user passed (NULL, 0), therefore ptr is known
63
+ // to be non-NULL, and UPB_PTRADD() is not necessary.
64
+ assert(a->ptr);
65
+ a->ptr += n;
66
+ } else {
67
+ a->ptr = UPB_PTRADD(a->ptr, have);
68
+ a->overflow += (n - have);
69
+ }
70
+ }
71
+
72
+ static size_t upb_FieldPath_NullTerminate(upb_PrintfAppender* d, size_t size) {
73
+ size_t ret = d->ptr - d->buf + d->overflow;
74
+
75
+ if (size > 0) {
76
+ if (d->ptr == d->end) d->ptr--;
77
+ *d->ptr = '\0';
78
+ }
79
+
80
+ return ret;
81
+ }
82
+
83
+ static void upb_FieldPath_PutMapKey(upb_PrintfAppender* a,
84
+ upb_MessageValue map_key,
85
+ const upb_FieldDef* key_f) {
86
+ switch (upb_FieldDef_CType(key_f)) {
87
+ case kUpb_CType_Int32:
88
+ upb_FieldPath_Printf(a, "[%" PRId32 "]", map_key.int32_val);
89
+ break;
90
+ case kUpb_CType_Int64:
91
+ upb_FieldPath_Printf(a, "[%" PRId64 "]", map_key.int64_val);
92
+ break;
93
+ case kUpb_CType_UInt32:
94
+ upb_FieldPath_Printf(a, "[%" PRIu32 "]", map_key.uint32_val);
95
+ break;
96
+ case kUpb_CType_UInt64:
97
+ upb_FieldPath_Printf(a, "[%" PRIu64 "]", map_key.uint64_val);
98
+ break;
99
+ case kUpb_CType_Bool:
100
+ upb_FieldPath_Printf(a, "[%s]", map_key.bool_val ? "true" : "false");
101
+ break;
102
+ case kUpb_CType_String:
103
+ upb_FieldPath_Printf(a, "[\"");
104
+ for (size_t i = 0; i < map_key.str_val.size; i++) {
105
+ char ch = map_key.str_val.data[i];
106
+ if (ch == '"') {
107
+ upb_FieldPath_Printf(a, "\\\"");
108
+ } else {
109
+ upb_FieldPath_Printf(a, "%c", ch);
110
+ }
111
+ }
112
+ upb_FieldPath_Printf(a, "\"]");
113
+ break;
114
+ default:
115
+ UPB_UNREACHABLE(); // Other types can't be map keys.
116
+ }
117
+ }
118
+
119
+ size_t upb_FieldPath_ToText(upb_FieldPathEntry** path, char* buf, size_t size) {
120
+ upb_FieldPathEntry* ptr = *path;
121
+ upb_PrintfAppender appender;
122
+ appender.buf = buf;
123
+ appender.ptr = buf;
124
+ appender.end = UPB_PTRADD(buf, size);
125
+ appender.overflow = 0;
126
+ bool first = true;
127
+
128
+ while (ptr->field) {
129
+ const upb_FieldDef* f = ptr->field;
130
+
131
+ upb_FieldPath_Printf(&appender, first ? "%s" : ".%s", upb_FieldDef_Name(f));
132
+ first = false;
133
+ ptr++;
134
+
135
+ if (upb_FieldDef_IsMap(f)) {
136
+ const upb_FieldDef* key_f =
137
+ upb_MessageDef_Field(upb_FieldDef_MessageSubDef(f), 0);
138
+ upb_FieldPath_PutMapKey(&appender, ptr->map_key, key_f);
139
+ ptr++;
140
+ } else if (upb_FieldDef_IsRepeated(f)) {
141
+ upb_FieldPath_Printf(&appender, "[%zu]", ptr->array_index);
142
+ ptr++;
143
+ }
144
+ }
145
+
146
+ // Advance beyond terminating NULL.
147
+ ptr++;
148
+ *path = ptr;
149
+ return upb_FieldPath_NullTerminate(&appender, size);
150
+ }
151
+
152
+ ////////////////////////////////////////////////////////////////////////////////
153
+ // upb_util_HasUnsetRequired()
154
+ ////////////////////////////////////////////////////////////////////////////////
155
+
156
+ typedef struct {
157
+ upb_FieldPathEntry* path;
158
+ size_t size;
159
+ size_t cap;
160
+ } upb_FieldPathVector;
161
+
162
+ typedef struct {
163
+ upb_FieldPathVector stack;
164
+ upb_FieldPathVector out_fields;
165
+ const upb_DefPool* ext_pool;
166
+ jmp_buf err;
167
+ bool has_unset_required;
168
+ bool save_paths;
169
+ } upb_FindContext;
170
+
171
+ static void upb_FieldPathVector_Init(upb_FieldPathVector* vec) {
172
+ vec->path = NULL;
173
+ vec->size = 0;
174
+ vec->cap = 0;
175
+ }
176
+
177
+ static void upb_FieldPathVector_Reserve(upb_FindContext* ctx,
178
+ upb_FieldPathVector* vec,
179
+ size_t elems) {
180
+ if (vec->cap - vec->size < elems) {
181
+ size_t need = vec->size + elems;
182
+ vec->cap = UPB_MAX(4, vec->cap);
183
+ while (vec->cap < need) vec->cap *= 2;
184
+ vec->path = realloc(vec->path, vec->cap * sizeof(*vec->path));
185
+ if (!vec->path) {
186
+ UPB_LONGJMP(ctx->err, 1);
187
+ }
188
+ }
189
+ }
190
+
191
+ static void upb_FindContext_Push(upb_FindContext* ctx, upb_FieldPathEntry ent) {
192
+ if (!ctx->save_paths) return;
193
+ upb_FieldPathVector_Reserve(ctx, &ctx->stack, 1);
194
+ ctx->stack.path[ctx->stack.size++] = ent;
195
+ }
196
+
197
+ static void upb_FindContext_Pop(upb_FindContext* ctx) {
198
+ if (!ctx->save_paths) return;
199
+ assert(ctx->stack.size != 0);
200
+ ctx->stack.size--;
201
+ }
202
+
203
+ static void upb_util_FindUnsetInMessage(upb_FindContext* ctx,
204
+ const upb_Message* msg,
205
+ const upb_MessageDef* m) {
206
+ // Iterate over all fields to see if any required fields are missing.
207
+ for (int i = 0, n = upb_MessageDef_FieldCount(m); i < n; i++) {
208
+ const upb_FieldDef* f = upb_MessageDef_Field(m, i);
209
+ if (upb_FieldDef_Label(f) != kUpb_Label_Required) continue;
210
+
211
+ if (!msg || !upb_Message_Has(msg, f)) {
212
+ // A required field is missing.
213
+ ctx->has_unset_required = true;
214
+
215
+ if (ctx->save_paths) {
216
+ // Append the contents of the stack to the out array, then
217
+ // NULL-terminate.
218
+ upb_FieldPathVector_Reserve(ctx, &ctx->out_fields, ctx->stack.size + 2);
219
+ if (ctx->stack.size) {
220
+ memcpy(&ctx->out_fields.path[ctx->out_fields.size], ctx->stack.path,
221
+ ctx->stack.size * sizeof(*ctx->stack.path));
222
+ }
223
+ ctx->out_fields.size += ctx->stack.size;
224
+ ctx->out_fields.path[ctx->out_fields.size++] =
225
+ (upb_FieldPathEntry){.field = f};
226
+ ctx->out_fields.path[ctx->out_fields.size++] =
227
+ (upb_FieldPathEntry){.field = NULL};
228
+ }
229
+ }
230
+ }
231
+ }
232
+
233
+ static void upb_util_FindUnsetRequiredInternal(upb_FindContext* ctx,
234
+ const upb_Message* msg,
235
+ const upb_MessageDef* m) {
236
+ // OPT: add markers in the schema for where we can avoid iterating:
237
+ // 1. messages with no required fields.
238
+ // 2. messages that cannot possibly reach any required fields.
239
+
240
+ upb_util_FindUnsetInMessage(ctx, msg, m);
241
+ if (!msg) return;
242
+
243
+ // Iterate over all present fields to find sub-messages that might be missing
244
+ // required fields. This may revisit some of the fields already inspected
245
+ // in the previous loop. We do this separately because this loop will also
246
+ // find present extensions, which the previous loop will not.
247
+ //
248
+ // TODO(haberman): consider changing upb_Message_Next() to be capable of
249
+ // visiting extensions only, for example with a kUpb_Message_BeginEXT
250
+ // constant.
251
+ size_t iter = kUpb_Message_Begin;
252
+ const upb_FieldDef* f;
253
+ upb_MessageValue val;
254
+ while (upb_Message_Next(msg, m, ctx->ext_pool, &f, &val, &iter)) {
255
+ // Skip non-submessage fields.
256
+ if (!upb_FieldDef_IsSubMessage(f)) continue;
257
+
258
+ upb_FindContext_Push(ctx, (upb_FieldPathEntry){.field = f});
259
+ const upb_MessageDef* sub_m = upb_FieldDef_MessageSubDef(f);
260
+
261
+ if (upb_FieldDef_IsMap(f)) {
262
+ // Map field.
263
+ const upb_FieldDef* val_f = upb_MessageDef_Field(sub_m, 1);
264
+ const upb_MessageDef* val_m = upb_FieldDef_MessageSubDef(val_f);
265
+ if (!val_m) continue;
266
+ const upb_Map* map = val.map_val;
267
+ size_t iter = kUpb_Map_Begin;
268
+ while (upb_MapIterator_Next(map, &iter)) {
269
+ upb_MessageValue key = upb_MapIterator_Key(map, iter);
270
+ upb_MessageValue map_val = upb_MapIterator_Value(map, iter);
271
+ upb_FindContext_Push(ctx, (upb_FieldPathEntry){.map_key = key});
272
+ upb_util_FindUnsetRequiredInternal(ctx, map_val.msg_val, val_m);
273
+ upb_FindContext_Pop(ctx);
274
+ }
275
+ } else if (upb_FieldDef_IsRepeated(f)) {
276
+ // Repeated field.
277
+ const upb_Array* arr = val.array_val;
278
+ for (size_t i = 0, n = upb_Array_Size(arr); i < n; i++) {
279
+ upb_MessageValue elem = upb_Array_Get(arr, i);
280
+ upb_FindContext_Push(ctx, (upb_FieldPathEntry){.array_index = i});
281
+ upb_util_FindUnsetRequiredInternal(ctx, elem.msg_val, sub_m);
282
+ upb_FindContext_Pop(ctx);
283
+ }
284
+ } else {
285
+ // Scalar sub-message field.
286
+ upb_util_FindUnsetRequiredInternal(ctx, val.msg_val, sub_m);
287
+ }
288
+
289
+ upb_FindContext_Pop(ctx);
290
+ }
291
+ }
292
+
293
+ bool upb_util_HasUnsetRequired(const upb_Message* msg, const upb_MessageDef* m,
294
+ const upb_DefPool* ext_pool,
295
+ upb_FieldPathEntry** fields) {
296
+ upb_FindContext ctx;
297
+ ctx.has_unset_required = false;
298
+ ctx.save_paths = fields != NULL;
299
+ ctx.ext_pool = ext_pool;
300
+ upb_FieldPathVector_Init(&ctx.stack);
301
+ upb_FieldPathVector_Init(&ctx.out_fields);
302
+ upb_util_FindUnsetRequiredInternal(&ctx, msg, m);
303
+ free(ctx.stack.path);
304
+ if (fields) {
305
+ upb_FieldPathVector_Reserve(&ctx, &ctx.out_fields, 1);
306
+ ctx.out_fields.path[ctx.out_fields.size] =
307
+ (upb_FieldPathEntry){.field = NULL};
308
+ *fields = ctx.out_fields.path;
309
+ }
310
+ return ctx.has_unset_required;
311
+ }