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,776 @@
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/json_encode.h"
29
+
30
+ #include <ctype.h>
31
+ #include <float.h>
32
+ #include <inttypes.h>
33
+ #include <math.h>
34
+ #include <setjmp.h>
35
+ #include <stdarg.h>
36
+ #include <stdio.h>
37
+ #include <string.h>
38
+
39
+ #include "upb/decode.h"
40
+ #include "upb/reflection.h"
41
+ #include "upb/upb_internal.h"
42
+
43
+ /* Must be last. */
44
+ #include "upb/port_def.inc"
45
+
46
+ typedef struct {
47
+ char *buf, *ptr, *end;
48
+ size_t overflow;
49
+ int indent_depth;
50
+ int options;
51
+ const upb_DefPool* ext_pool;
52
+ jmp_buf err;
53
+ upb_Status* status;
54
+ upb_Arena* arena;
55
+ } jsonenc;
56
+
57
+ static void jsonenc_msg(jsonenc* e, const upb_Message* msg,
58
+ const upb_MessageDef* m);
59
+ static void jsonenc_scalar(jsonenc* e, upb_MessageValue val,
60
+ const upb_FieldDef* f);
61
+ static void jsonenc_msgfield(jsonenc* e, const upb_Message* msg,
62
+ const upb_MessageDef* m);
63
+ static void jsonenc_msgfields(jsonenc* e, const upb_Message* msg,
64
+ const upb_MessageDef* m, bool first);
65
+ static void jsonenc_value(jsonenc* e, const upb_Message* msg,
66
+ const upb_MessageDef* m);
67
+
68
+ UPB_NORETURN static void jsonenc_err(jsonenc* e, const char* msg) {
69
+ upb_Status_SetErrorMessage(e->status, msg);
70
+ longjmp(e->err, 1);
71
+ }
72
+
73
+ UPB_PRINTF(2, 3)
74
+ UPB_NORETURN static void jsonenc_errf(jsonenc* e, const char* fmt, ...) {
75
+ va_list argp;
76
+ va_start(argp, fmt);
77
+ upb_Status_VSetErrorFormat(e->status, fmt, argp);
78
+ va_end(argp);
79
+ longjmp(e->err, 1);
80
+ }
81
+
82
+ static upb_Arena* jsonenc_arena(jsonenc* e) {
83
+ /* Create lazily, since it's only needed for Any */
84
+ if (!e->arena) {
85
+ e->arena = upb_Arena_New();
86
+ }
87
+ return e->arena;
88
+ }
89
+
90
+ static void jsonenc_putbytes(jsonenc* e, const void* data, size_t len) {
91
+ size_t have = e->end - e->ptr;
92
+ if (UPB_LIKELY(have >= len)) {
93
+ memcpy(e->ptr, data, len);
94
+ e->ptr += len;
95
+ } else {
96
+ if (have) {
97
+ memcpy(e->ptr, data, have);
98
+ e->ptr += have;
99
+ }
100
+ e->overflow += (len - have);
101
+ }
102
+ }
103
+
104
+ static void jsonenc_putstr(jsonenc* e, const char* str) {
105
+ jsonenc_putbytes(e, str, strlen(str));
106
+ }
107
+
108
+ UPB_PRINTF(2, 3)
109
+ static void jsonenc_printf(jsonenc* e, const char* fmt, ...) {
110
+ size_t n;
111
+ size_t have = e->end - e->ptr;
112
+ va_list args;
113
+
114
+ va_start(args, fmt);
115
+ n = vsnprintf(e->ptr, have, fmt, args);
116
+ va_end(args);
117
+
118
+ if (UPB_LIKELY(have > n)) {
119
+ e->ptr += n;
120
+ } else {
121
+ e->ptr = UPB_PTRADD(e->ptr, have);
122
+ e->overflow += (n - have);
123
+ }
124
+ }
125
+
126
+ static void jsonenc_nanos(jsonenc* e, int32_t nanos) {
127
+ int digits = 9;
128
+
129
+ if (nanos == 0) return;
130
+ if (nanos < 0 || nanos >= 1000000000) {
131
+ jsonenc_err(e, "error formatting timestamp as JSON: invalid nanos");
132
+ }
133
+
134
+ while (nanos % 1000 == 0) {
135
+ nanos /= 1000;
136
+ digits -= 3;
137
+ }
138
+
139
+ jsonenc_printf(e, ".%.*" PRId32, digits, nanos);
140
+ }
141
+
142
+ static void jsonenc_timestamp(jsonenc* e, const upb_Message* msg,
143
+ const upb_MessageDef* m) {
144
+ const upb_FieldDef* seconds_f = upb_MessageDef_FindFieldByNumber(m, 1);
145
+ const upb_FieldDef* nanos_f = upb_MessageDef_FindFieldByNumber(m, 2);
146
+ int64_t seconds = upb_Message_Get(msg, seconds_f).int64_val;
147
+ int32_t nanos = upb_Message_Get(msg, nanos_f).int32_val;
148
+ int L, N, I, J, K, hour, min, sec;
149
+
150
+ if (seconds < -62135596800) {
151
+ jsonenc_err(e,
152
+ "error formatting timestamp as JSON: minimum acceptable value "
153
+ "is 0001-01-01T00:00:00Z");
154
+ } else if (seconds > 253402300799) {
155
+ jsonenc_err(e,
156
+ "error formatting timestamp as JSON: maximum acceptable value "
157
+ "is 9999-12-31T23:59:59Z");
158
+ }
159
+
160
+ /* Julian Day -> Y/M/D, Algorithm from:
161
+ * Fliegel, H. F., and Van Flandern, T. C., "A Machine Algorithm for
162
+ * Processing Calendar Dates," Communications of the Association of
163
+ * Computing Machines, vol. 11 (1968), p. 657. */
164
+ seconds += 62135596800; // Ensure seconds is positive.
165
+ L = (int)(seconds / 86400) - 719162 + 68569 + 2440588;
166
+ N = 4 * L / 146097;
167
+ L = L - (146097 * N + 3) / 4;
168
+ I = 4000 * (L + 1) / 1461001;
169
+ L = L - 1461 * I / 4 + 31;
170
+ J = 80 * L / 2447;
171
+ K = L - 2447 * J / 80;
172
+ L = J / 11;
173
+ J = J + 2 - 12 * L;
174
+ I = 100 * (N - 49) + I + L;
175
+
176
+ sec = seconds % 60;
177
+ min = (seconds / 60) % 60;
178
+ hour = (seconds / 3600) % 24;
179
+
180
+ jsonenc_printf(e, "\"%04d-%02d-%02dT%02d:%02d:%02d", I, J, K, hour, min, sec);
181
+ jsonenc_nanos(e, nanos);
182
+ jsonenc_putstr(e, "Z\"");
183
+ }
184
+
185
+ static void jsonenc_duration(jsonenc* e, const upb_Message* msg,
186
+ const upb_MessageDef* m) {
187
+ const upb_FieldDef* seconds_f = upb_MessageDef_FindFieldByNumber(m, 1);
188
+ const upb_FieldDef* nanos_f = upb_MessageDef_FindFieldByNumber(m, 2);
189
+ int64_t seconds = upb_Message_Get(msg, seconds_f).int64_val;
190
+ int32_t nanos = upb_Message_Get(msg, nanos_f).int32_val;
191
+
192
+ if (seconds > 315576000000 || seconds < -315576000000 ||
193
+ (seconds < 0) != (nanos < 0)) {
194
+ jsonenc_err(e, "bad duration");
195
+ }
196
+
197
+ if (nanos < 0) {
198
+ nanos = -nanos;
199
+ }
200
+
201
+ jsonenc_printf(e, "\"%" PRId64, seconds);
202
+ jsonenc_nanos(e, nanos);
203
+ jsonenc_putstr(e, "s\"");
204
+ }
205
+
206
+ static void jsonenc_enum(int32_t val, const upb_FieldDef* f, jsonenc* e) {
207
+ const upb_EnumDef* e_def = upb_FieldDef_EnumSubDef(f);
208
+
209
+ if (strcmp(upb_EnumDef_FullName(e_def), "google.protobuf.NullValue") == 0) {
210
+ jsonenc_putstr(e, "null");
211
+ } else {
212
+ const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNumber(e_def, val);
213
+
214
+ if (ev) {
215
+ jsonenc_printf(e, "\"%s\"", upb_EnumValueDef_Name(ev));
216
+ } else {
217
+ jsonenc_printf(e, "%" PRId32, val);
218
+ }
219
+ }
220
+ }
221
+
222
+ static void jsonenc_bytes(jsonenc* e, upb_StringView str) {
223
+ /* This is the regular base64, not the "web-safe" version. */
224
+ static const char base64[] =
225
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
226
+ const unsigned char* ptr = (unsigned char*)str.data;
227
+ const unsigned char* end = UPB_PTRADD(ptr, str.size);
228
+ char buf[4];
229
+
230
+ jsonenc_putstr(e, "\"");
231
+
232
+ while (end - ptr >= 3) {
233
+ buf[0] = base64[ptr[0] >> 2];
234
+ buf[1] = base64[((ptr[0] & 0x3) << 4) | (ptr[1] >> 4)];
235
+ buf[2] = base64[((ptr[1] & 0xf) << 2) | (ptr[2] >> 6)];
236
+ buf[3] = base64[ptr[2] & 0x3f];
237
+ jsonenc_putbytes(e, buf, 4);
238
+ ptr += 3;
239
+ }
240
+
241
+ switch (end - ptr) {
242
+ case 2:
243
+ buf[0] = base64[ptr[0] >> 2];
244
+ buf[1] = base64[((ptr[0] & 0x3) << 4) | (ptr[1] >> 4)];
245
+ buf[2] = base64[(ptr[1] & 0xf) << 2];
246
+ buf[3] = '=';
247
+ jsonenc_putbytes(e, buf, 4);
248
+ break;
249
+ case 1:
250
+ buf[0] = base64[ptr[0] >> 2];
251
+ buf[1] = base64[((ptr[0] & 0x3) << 4)];
252
+ buf[2] = '=';
253
+ buf[3] = '=';
254
+ jsonenc_putbytes(e, buf, 4);
255
+ break;
256
+ }
257
+
258
+ jsonenc_putstr(e, "\"");
259
+ }
260
+
261
+ static void jsonenc_stringbody(jsonenc* e, upb_StringView str) {
262
+ const char* ptr = str.data;
263
+ const char* end = UPB_PTRADD(ptr, str.size);
264
+
265
+ while (ptr < end) {
266
+ switch (*ptr) {
267
+ case '\n':
268
+ jsonenc_putstr(e, "\\n");
269
+ break;
270
+ case '\r':
271
+ jsonenc_putstr(e, "\\r");
272
+ break;
273
+ case '\t':
274
+ jsonenc_putstr(e, "\\t");
275
+ break;
276
+ case '\"':
277
+ jsonenc_putstr(e, "\\\"");
278
+ break;
279
+ case '\f':
280
+ jsonenc_putstr(e, "\\f");
281
+ break;
282
+ case '\b':
283
+ jsonenc_putstr(e, "\\b");
284
+ break;
285
+ case '\\':
286
+ jsonenc_putstr(e, "\\\\");
287
+ break;
288
+ default:
289
+ if ((uint8_t)*ptr < 0x20) {
290
+ jsonenc_printf(e, "\\u%04x", (int)(uint8_t)*ptr);
291
+ } else {
292
+ /* This could be a non-ASCII byte. We rely on the string being valid
293
+ * UTF-8. */
294
+ jsonenc_putbytes(e, ptr, 1);
295
+ }
296
+ break;
297
+ }
298
+ ptr++;
299
+ }
300
+ }
301
+
302
+ static void jsonenc_string(jsonenc* e, upb_StringView str) {
303
+ jsonenc_putstr(e, "\"");
304
+ jsonenc_stringbody(e, str);
305
+ jsonenc_putstr(e, "\"");
306
+ }
307
+
308
+ static bool upb_JsonEncode_HandleSpecialDoubles(jsonenc* e, double val) {
309
+ if (val == INFINITY) {
310
+ jsonenc_putstr(e, "\"Infinity\"");
311
+ } else if (val == -INFINITY) {
312
+ jsonenc_putstr(e, "\"-Infinity\"");
313
+ } else if (val != val) {
314
+ jsonenc_putstr(e, "\"NaN\"");
315
+ } else {
316
+ return false;
317
+ }
318
+ return true;
319
+ }
320
+
321
+ static void upb_JsonEncode_Double(jsonenc* e, double val) {
322
+ if (upb_JsonEncode_HandleSpecialDoubles(e, val)) return;
323
+ char buf[32];
324
+ _upb_EncodeRoundTripDouble(val, buf, sizeof(buf));
325
+ jsonenc_putstr(e, buf);
326
+ }
327
+
328
+ static void upb_JsonEncode_Float(jsonenc* e, float val) {
329
+ if (upb_JsonEncode_HandleSpecialDoubles(e, val)) return;
330
+ char buf[32];
331
+ _upb_EncodeRoundTripFloat(val, buf, sizeof(buf));
332
+ jsonenc_putstr(e, buf);
333
+ }
334
+
335
+ static void jsonenc_wrapper(jsonenc* e, const upb_Message* msg,
336
+ const upb_MessageDef* m) {
337
+ const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(m, 1);
338
+ upb_MessageValue val = upb_Message_Get(msg, val_f);
339
+ jsonenc_scalar(e, val, val_f);
340
+ }
341
+
342
+ static const upb_MessageDef* jsonenc_getanymsg(jsonenc* e,
343
+ upb_StringView type_url) {
344
+ /* Find last '/', if any. */
345
+ const char* end = type_url.data + type_url.size;
346
+ const char* ptr = end;
347
+ const upb_MessageDef* ret;
348
+
349
+ if (!e->ext_pool) {
350
+ jsonenc_err(e, "Tried to encode Any, but no symtab was provided");
351
+ }
352
+
353
+ if (type_url.size == 0) goto badurl;
354
+
355
+ while (true) {
356
+ if (--ptr == type_url.data) {
357
+ /* Type URL must contain at least one '/', with host before. */
358
+ goto badurl;
359
+ }
360
+ if (*ptr == '/') {
361
+ ptr++;
362
+ break;
363
+ }
364
+ }
365
+
366
+ ret = upb_DefPool_FindMessageByNameWithSize(e->ext_pool, ptr, end - ptr);
367
+
368
+ if (!ret) {
369
+ jsonenc_errf(e, "Couldn't find Any type: %.*s", (int)(end - ptr), ptr);
370
+ }
371
+
372
+ return ret;
373
+
374
+ badurl:
375
+ jsonenc_errf(e, "Bad type URL: " UPB_STRINGVIEW_FORMAT,
376
+ UPB_STRINGVIEW_ARGS(type_url));
377
+ }
378
+
379
+ static void jsonenc_any(jsonenc* e, const upb_Message* msg,
380
+ const upb_MessageDef* m) {
381
+ const upb_FieldDef* type_url_f = upb_MessageDef_FindFieldByNumber(m, 1);
382
+ const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(m, 2);
383
+ upb_StringView type_url = upb_Message_Get(msg, type_url_f).str_val;
384
+ upb_StringView value = upb_Message_Get(msg, value_f).str_val;
385
+ const upb_MessageDef* any_m = jsonenc_getanymsg(e, type_url);
386
+ const upb_MiniTable* any_layout = upb_MessageDef_MiniTable(any_m);
387
+ upb_Arena* arena = jsonenc_arena(e);
388
+ upb_Message* any = upb_Message_New(any_m, arena);
389
+
390
+ if (upb_Decode(value.data, value.size, any, any_layout, NULL, 0, arena) !=
391
+ kUpb_DecodeStatus_Ok) {
392
+ jsonenc_err(e, "Error decoding message in Any");
393
+ }
394
+
395
+ jsonenc_putstr(e, "{\"@type\":");
396
+ jsonenc_string(e, type_url);
397
+
398
+ if (upb_MessageDef_WellKnownType(any_m) == kUpb_WellKnown_Unspecified) {
399
+ /* Regular messages: {"@type": "...","foo": 1, "bar": 2} */
400
+ jsonenc_msgfields(e, any, any_m, false);
401
+ } else {
402
+ /* Well-known type: {"@type": "...","value": <well-known encoding>} */
403
+ jsonenc_putstr(e, ",\"value\":");
404
+ jsonenc_msgfield(e, any, any_m);
405
+ }
406
+
407
+ jsonenc_putstr(e, "}");
408
+ }
409
+
410
+ static void jsonenc_putsep(jsonenc* e, const char* str, bool* first) {
411
+ if (*first) {
412
+ *first = false;
413
+ } else {
414
+ jsonenc_putstr(e, str);
415
+ }
416
+ }
417
+
418
+ static void jsonenc_fieldpath(jsonenc* e, upb_StringView path) {
419
+ const char* ptr = path.data;
420
+ const char* end = ptr + path.size;
421
+
422
+ while (ptr < end) {
423
+ char ch = *ptr;
424
+
425
+ if (ch >= 'A' && ch <= 'Z') {
426
+ jsonenc_err(e, "Field mask element may not have upper-case letter.");
427
+ } else if (ch == '_') {
428
+ if (ptr == end - 1 || *(ptr + 1) < 'a' || *(ptr + 1) > 'z') {
429
+ jsonenc_err(e, "Underscore must be followed by a lowercase letter.");
430
+ }
431
+ ch = *++ptr - 32;
432
+ }
433
+
434
+ jsonenc_putbytes(e, &ch, 1);
435
+ ptr++;
436
+ }
437
+ }
438
+
439
+ static void jsonenc_fieldmask(jsonenc* e, const upb_Message* msg,
440
+ const upb_MessageDef* m) {
441
+ const upb_FieldDef* paths_f = upb_MessageDef_FindFieldByNumber(m, 1);
442
+ const upb_Array* paths = upb_Message_Get(msg, paths_f).array_val;
443
+ bool first = true;
444
+ size_t i, n = 0;
445
+
446
+ if (paths) n = upb_Array_Size(paths);
447
+
448
+ jsonenc_putstr(e, "\"");
449
+
450
+ for (i = 0; i < n; i++) {
451
+ jsonenc_putsep(e, ",", &first);
452
+ jsonenc_fieldpath(e, upb_Array_Get(paths, i).str_val);
453
+ }
454
+
455
+ jsonenc_putstr(e, "\"");
456
+ }
457
+
458
+ static void jsonenc_struct(jsonenc* e, const upb_Message* msg,
459
+ const upb_MessageDef* m) {
460
+ const upb_FieldDef* fields_f = upb_MessageDef_FindFieldByNumber(m, 1);
461
+ const upb_Map* fields = upb_Message_Get(msg, fields_f).map_val;
462
+ const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(fields_f);
463
+ const upb_FieldDef* value_f = upb_MessageDef_FindFieldByNumber(entry_m, 2);
464
+ size_t iter = kUpb_Map_Begin;
465
+ bool first = true;
466
+
467
+ jsonenc_putstr(e, "{");
468
+
469
+ if (fields) {
470
+ while (upb_MapIterator_Next(fields, &iter)) {
471
+ upb_MessageValue key = upb_MapIterator_Key(fields, iter);
472
+ upb_MessageValue val = upb_MapIterator_Value(fields, iter);
473
+
474
+ jsonenc_putsep(e, ",", &first);
475
+ jsonenc_string(e, key.str_val);
476
+ jsonenc_putstr(e, ":");
477
+ jsonenc_value(e, val.msg_val, upb_FieldDef_MessageSubDef(value_f));
478
+ }
479
+ }
480
+
481
+ jsonenc_putstr(e, "}");
482
+ }
483
+
484
+ static void jsonenc_listvalue(jsonenc* e, const upb_Message* msg,
485
+ const upb_MessageDef* m) {
486
+ const upb_FieldDef* values_f = upb_MessageDef_FindFieldByNumber(m, 1);
487
+ const upb_MessageDef* values_m = upb_FieldDef_MessageSubDef(values_f);
488
+ const upb_Array* values = upb_Message_Get(msg, values_f).array_val;
489
+ size_t i;
490
+ bool first = true;
491
+
492
+ jsonenc_putstr(e, "[");
493
+
494
+ if (values) {
495
+ const size_t size = upb_Array_Size(values);
496
+ for (i = 0; i < size; i++) {
497
+ upb_MessageValue elem = upb_Array_Get(values, i);
498
+
499
+ jsonenc_putsep(e, ",", &first);
500
+ jsonenc_value(e, elem.msg_val, values_m);
501
+ }
502
+ }
503
+
504
+ jsonenc_putstr(e, "]");
505
+ }
506
+
507
+ static void jsonenc_value(jsonenc* e, const upb_Message* msg,
508
+ const upb_MessageDef* m) {
509
+ /* TODO(haberman): do we want a reflection method to get oneof case? */
510
+ size_t iter = kUpb_Message_Begin;
511
+ const upb_FieldDef* f;
512
+ upb_MessageValue val;
513
+
514
+ if (!upb_Message_Next(msg, m, NULL, &f, &val, &iter)) {
515
+ jsonenc_err(e, "No value set in Value proto");
516
+ }
517
+
518
+ switch (upb_FieldDef_Number(f)) {
519
+ case 1:
520
+ jsonenc_putstr(e, "null");
521
+ break;
522
+ case 2:
523
+ upb_JsonEncode_Double(e, val.double_val);
524
+ break;
525
+ case 3:
526
+ jsonenc_string(e, val.str_val);
527
+ break;
528
+ case 4:
529
+ jsonenc_putstr(e, val.bool_val ? "true" : "false");
530
+ break;
531
+ case 5:
532
+ jsonenc_struct(e, val.msg_val, upb_FieldDef_MessageSubDef(f));
533
+ break;
534
+ case 6:
535
+ jsonenc_listvalue(e, val.msg_val, upb_FieldDef_MessageSubDef(f));
536
+ break;
537
+ }
538
+ }
539
+
540
+ static void jsonenc_msgfield(jsonenc* e, const upb_Message* msg,
541
+ const upb_MessageDef* m) {
542
+ switch (upb_MessageDef_WellKnownType(m)) {
543
+ case kUpb_WellKnown_Unspecified:
544
+ jsonenc_msg(e, msg, m);
545
+ break;
546
+ case kUpb_WellKnown_Any:
547
+ jsonenc_any(e, msg, m);
548
+ break;
549
+ case kUpb_WellKnown_FieldMask:
550
+ jsonenc_fieldmask(e, msg, m);
551
+ break;
552
+ case kUpb_WellKnown_Duration:
553
+ jsonenc_duration(e, msg, m);
554
+ break;
555
+ case kUpb_WellKnown_Timestamp:
556
+ jsonenc_timestamp(e, msg, m);
557
+ break;
558
+ case kUpb_WellKnown_DoubleValue:
559
+ case kUpb_WellKnown_FloatValue:
560
+ case kUpb_WellKnown_Int64Value:
561
+ case kUpb_WellKnown_UInt64Value:
562
+ case kUpb_WellKnown_Int32Value:
563
+ case kUpb_WellKnown_UInt32Value:
564
+ case kUpb_WellKnown_StringValue:
565
+ case kUpb_WellKnown_BytesValue:
566
+ case kUpb_WellKnown_BoolValue:
567
+ jsonenc_wrapper(e, msg, m);
568
+ break;
569
+ case kUpb_WellKnown_Value:
570
+ jsonenc_value(e, msg, m);
571
+ break;
572
+ case kUpb_WellKnown_ListValue:
573
+ jsonenc_listvalue(e, msg, m);
574
+ break;
575
+ case kUpb_WellKnown_Struct:
576
+ jsonenc_struct(e, msg, m);
577
+ break;
578
+ }
579
+ }
580
+
581
+ static void jsonenc_scalar(jsonenc* e, upb_MessageValue val,
582
+ const upb_FieldDef* f) {
583
+ switch (upb_FieldDef_CType(f)) {
584
+ case kUpb_CType_Bool:
585
+ jsonenc_putstr(e, val.bool_val ? "true" : "false");
586
+ break;
587
+ case kUpb_CType_Float:
588
+ upb_JsonEncode_Float(e, val.float_val);
589
+ break;
590
+ case kUpb_CType_Double:
591
+ upb_JsonEncode_Double(e, val.double_val);
592
+ break;
593
+ case kUpb_CType_Int32:
594
+ jsonenc_printf(e, "%" PRId32, val.int32_val);
595
+ break;
596
+ case kUpb_CType_UInt32:
597
+ jsonenc_printf(e, "%" PRIu32, val.uint32_val);
598
+ break;
599
+ case kUpb_CType_Int64:
600
+ jsonenc_printf(e, "\"%" PRId64 "\"", val.int64_val);
601
+ break;
602
+ case kUpb_CType_UInt64:
603
+ jsonenc_printf(e, "\"%" PRIu64 "\"", val.uint64_val);
604
+ break;
605
+ case kUpb_CType_String:
606
+ jsonenc_string(e, val.str_val);
607
+ break;
608
+ case kUpb_CType_Bytes:
609
+ jsonenc_bytes(e, val.str_val);
610
+ break;
611
+ case kUpb_CType_Enum:
612
+ jsonenc_enum(val.int32_val, f, e);
613
+ break;
614
+ case kUpb_CType_Message:
615
+ jsonenc_msgfield(e, val.msg_val, upb_FieldDef_MessageSubDef(f));
616
+ break;
617
+ }
618
+ }
619
+
620
+ static void jsonenc_mapkey(jsonenc* e, upb_MessageValue val,
621
+ const upb_FieldDef* f) {
622
+ jsonenc_putstr(e, "\"");
623
+
624
+ switch (upb_FieldDef_CType(f)) {
625
+ case kUpb_CType_Bool:
626
+ jsonenc_putstr(e, val.bool_val ? "true" : "false");
627
+ break;
628
+ case kUpb_CType_Int32:
629
+ jsonenc_printf(e, "%" PRId32, val.int32_val);
630
+ break;
631
+ case kUpb_CType_UInt32:
632
+ jsonenc_printf(e, "%" PRIu32, val.uint32_val);
633
+ break;
634
+ case kUpb_CType_Int64:
635
+ jsonenc_printf(e, "%" PRId64, val.int64_val);
636
+ break;
637
+ case kUpb_CType_UInt64:
638
+ jsonenc_printf(e, "%" PRIu64, val.uint64_val);
639
+ break;
640
+ case kUpb_CType_String:
641
+ jsonenc_stringbody(e, val.str_val);
642
+ break;
643
+ default:
644
+ UPB_UNREACHABLE();
645
+ }
646
+
647
+ jsonenc_putstr(e, "\":");
648
+ }
649
+
650
+ static void jsonenc_array(jsonenc* e, const upb_Array* arr,
651
+ const upb_FieldDef* f) {
652
+ size_t i;
653
+ size_t size = arr ? upb_Array_Size(arr) : 0;
654
+ bool first = true;
655
+
656
+ jsonenc_putstr(e, "[");
657
+
658
+ for (i = 0; i < size; i++) {
659
+ jsonenc_putsep(e, ",", &first);
660
+ jsonenc_scalar(e, upb_Array_Get(arr, i), f);
661
+ }
662
+
663
+ jsonenc_putstr(e, "]");
664
+ }
665
+
666
+ static void jsonenc_map(jsonenc* e, const upb_Map* map, const upb_FieldDef* f) {
667
+ const upb_MessageDef* entry = upb_FieldDef_MessageSubDef(f);
668
+ const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry, 1);
669
+ const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry, 2);
670
+ size_t iter = kUpb_Map_Begin;
671
+ bool first = true;
672
+
673
+ jsonenc_putstr(e, "{");
674
+
675
+ if (map) {
676
+ while (upb_MapIterator_Next(map, &iter)) {
677
+ jsonenc_putsep(e, ",", &first);
678
+ jsonenc_mapkey(e, upb_MapIterator_Key(map, iter), key_f);
679
+ jsonenc_scalar(e, upb_MapIterator_Value(map, iter), val_f);
680
+ }
681
+ }
682
+
683
+ jsonenc_putstr(e, "}");
684
+ }
685
+
686
+ static void jsonenc_fieldval(jsonenc* e, const upb_FieldDef* f,
687
+ upb_MessageValue val, bool* first) {
688
+ const char* name;
689
+
690
+ jsonenc_putsep(e, ",", first);
691
+
692
+ if (upb_FieldDef_IsExtension(f)) {
693
+ // TODO: For MessageSet, I would have expected this to print the message
694
+ // name here, but Python doesn't appear to do this. We should do more
695
+ // research here about what various implementations do.
696
+ jsonenc_printf(e, "\"[%s]\":", upb_FieldDef_FullName(f));
697
+ } else {
698
+ if (e->options & upb_JsonEncode_UseProtoNames) {
699
+ name = upb_FieldDef_Name(f);
700
+ } else {
701
+ name = upb_FieldDef_JsonName(f);
702
+ }
703
+ jsonenc_printf(e, "\"%s\":", name);
704
+ }
705
+
706
+ if (upb_FieldDef_IsMap(f)) {
707
+ jsonenc_map(e, val.map_val, f);
708
+ } else if (upb_FieldDef_IsRepeated(f)) {
709
+ jsonenc_array(e, val.array_val, f);
710
+ } else {
711
+ jsonenc_scalar(e, val, f);
712
+ }
713
+ }
714
+
715
+ static void jsonenc_msgfields(jsonenc* e, const upb_Message* msg,
716
+ const upb_MessageDef* m, bool first) {
717
+ upb_MessageValue val;
718
+ const upb_FieldDef* f;
719
+
720
+ if (e->options & upb_JsonEncode_EmitDefaults) {
721
+ /* Iterate over all fields. */
722
+ int i = 0;
723
+ int n = upb_MessageDef_FieldCount(m);
724
+ for (i = 0; i < n; i++) {
725
+ f = upb_MessageDef_Field(m, i);
726
+ if (!upb_FieldDef_HasPresence(f) || upb_Message_Has(msg, f)) {
727
+ jsonenc_fieldval(e, f, upb_Message_Get(msg, f), &first);
728
+ }
729
+ }
730
+ } else {
731
+ /* Iterate over non-empty fields. */
732
+ size_t iter = kUpb_Message_Begin;
733
+ while (upb_Message_Next(msg, m, e->ext_pool, &f, &val, &iter)) {
734
+ jsonenc_fieldval(e, f, val, &first);
735
+ }
736
+ }
737
+ }
738
+
739
+ static void jsonenc_msg(jsonenc* e, const upb_Message* msg,
740
+ const upb_MessageDef* m) {
741
+ jsonenc_putstr(e, "{");
742
+ jsonenc_msgfields(e, msg, m, true);
743
+ jsonenc_putstr(e, "}");
744
+ }
745
+
746
+ static size_t jsonenc_nullz(jsonenc* e, size_t size) {
747
+ size_t ret = e->ptr - e->buf + e->overflow;
748
+
749
+ if (size > 0) {
750
+ if (e->ptr == e->end) e->ptr--;
751
+ *e->ptr = '\0';
752
+ }
753
+
754
+ return ret;
755
+ }
756
+
757
+ size_t upb_JsonEncode(const upb_Message* msg, const upb_MessageDef* m,
758
+ const upb_DefPool* ext_pool, int options, char* buf,
759
+ size_t size, upb_Status* status) {
760
+ jsonenc e;
761
+
762
+ e.buf = buf;
763
+ e.ptr = buf;
764
+ e.end = UPB_PTRADD(buf, size);
765
+ e.overflow = 0;
766
+ e.options = options;
767
+ e.ext_pool = ext_pool;
768
+ e.status = status;
769
+ e.arena = NULL;
770
+
771
+ if (setjmp(e.err)) return -1;
772
+
773
+ jsonenc_msgfield(&e, msg, m);
774
+ if (e.arena) upb_Arena_Free(e.arena);
775
+ return jsonenc_nullz(&e, size);
776
+ }