ruby_memprofiler_pprof 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/ruby_memprofiler_pprof/backtrace.c +429 -0
- data/ext/ruby_memprofiler_pprof/collector.c +1055 -0
- data/ext/ruby_memprofiler_pprof/compat.c +182 -0
- data/ext/ruby_memprofiler_pprof/extconf.rb +72 -0
- data/ext/ruby_memprofiler_pprof/pprof.upb.c +170 -0
- data/ext/ruby_memprofiler_pprof/pprof.upb.h +848 -0
- data/ext/ruby_memprofiler_pprof/pprof_out.c +285 -0
- data/ext/ruby_memprofiler_pprof/ruby_memprofiler_pprof.c +11 -0
- data/ext/ruby_memprofiler_pprof/ruby_memprofiler_pprof.h +301 -0
- data/ext/ruby_memprofiler_pprof/strtab.c +391 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/BUILD +719 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/CONTRIBUTING.md +37 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/DESIGN.md +201 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/LICENSE +26 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/README.md +78 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/WORKSPACE +58 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/BUILD +53 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/amalgamate.py +129 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/build_defs.bzl +160 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/lua.BUILD +127 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/protobuf.patch +54 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/py_proto_library.bzl +137 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/python_downloads.bzl +84 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/system_python.bzl +101 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/upb_proto_library.bzl +388 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/bazel/workspace_deps.bzl +89 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/BUILD +252 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/BUILD.googleapis +54 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/benchmark.cc +333 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/build_defs.bzl +88 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/compare.py +118 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/descriptor.proto +888 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/descriptor_sv.proto +890 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/empty.proto +6 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/gen_protobuf_binary_cc.py +64 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/gen_synthetic_protos.py +118 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/benchmarks/gen_upb_binary_c.py +65 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/BUILD.bazel +102 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/README.md +23 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/build_defs.bzl +73 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/make_cmakelists.py +340 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/staleness_test.py +57 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/cmake/staleness_test_lib.py +186 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/docs/render.py +43 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/docs/style-guide.md +65 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/docs/vs-cpp-protos.md +255 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/docs/wrapping-upb.md +444 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/BUILD +216 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/convert.c +394 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/convert.h +63 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor.c +1694 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor.h +80 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor_containers.c +704 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor_containers.h +114 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor_pool.c +650 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/descriptor_pool.h +48 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/dist/BUILD.bazel +193 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/dist/dist.bzl +190 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/extension_dict.c +247 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/extension_dict.h +39 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/map.c +522 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/map.h +66 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/message.c +1909 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/message.h +101 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/minimal_test.py +183 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/BUILD +70 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/README.md +11 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/descriptor_database_test_wrapper.py +30 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/descriptor_pool_test_wrapper.py +45 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/descriptor_test_wrapper.py +46 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/generator_test_wrapper.py +30 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/json_format_test_wrapper.py +30 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/keywords_test_wrapper.py +30 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/message_factory_test_wrapper.py +37 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/message_test_wrapper.py +52 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/proto_builder_test_wrapper.py +32 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/pyproto_test_wrapper.bzl +36 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/reflection_test_wrapper.py +45 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/service_reflection_test_wrapper.py +30 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/symbol_database_test_wrapper.py +30 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/text_encoding_test_wrapper.py +30 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/text_format_test_wrapper.py +30 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/unknown_fields_test_wrapper.py +30 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/well_known_types_test_wrapper.py +36 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/pb_unit_tests/wire_format_test_wrapper.py +30 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/protobuf.c +350 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/protobuf.h +230 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/py_extension.bzl +55 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/python_api.h +61 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/repeated.c +828 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/repeated.h +69 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/unknown_fields.c +404 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/unknown_fields.h +39 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/python/version_script.lds +6 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/lunit/LICENSE +32 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/lunit/README.google +9 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/lunit/console.lua +156 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/lunit/lunit.lua +725 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/BUILD +19 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/LICENSE +21 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/naive.c +92 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/range2-neon.c +157 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/range2-sse.c +170 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/third_party/utf8_range/utf8_range.h +9 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/BUILD.bazel +129 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/README.md +8 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/def.c +939 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/lua_proto_library.bzl +138 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/main.c +83 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/msg.c +1118 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/test.proto +69 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/test_upb.lua +846 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/upb.c +258 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/upb.h +132 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/upb.lua +58 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/bindings/lua/upbc.cc +134 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/collections.c +192 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/collections.h +174 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/conformance_upb.c +346 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/conformance_upb_failures.txt +1 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/decode.c +1221 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/decode.h +94 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/decode_fast.c +1055 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/decode_fast.h +153 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/decode_internal.h +211 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/def.c +3262 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/def.h +414 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/def.hpp +438 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/empty.proto +1 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/encode.c +604 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/encode.h +71 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/fuzz/BUILD +13 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/fuzz/file_descriptor_parsenew_fuzzer.cc +43 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/json_decode.c +1509 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/json_decode.h +47 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/json_encode.c +776 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/json_encode.h +62 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table.c +1147 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table.h +189 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table.hpp +112 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table_accessors.c +363 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table_accessors.h +263 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table_accessors_internal.h +59 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table_accessors_test.cc +425 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/mini_table_test.cc +230 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/msg.c +428 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/msg.h +114 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/msg_internal.h +836 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/msg_test.cc +491 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/msg_test.proto +195 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/port_def.inc +261 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/port_undef.inc +62 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/reflection.c +323 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/reflection.h +109 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/reflection.hpp +37 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/table.c +926 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/table_internal.h +385 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/test.proto +74 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/test_cpp.cc +186 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/test_cpp.proto +12 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/test_generated_code.cc +977 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/test_table.cc +580 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/text_encode.c +472 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/text_encode.h +64 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/upb.c +362 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/upb.h +378 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/upb.hpp +115 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/upb_internal.h +68 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/BUILD +121 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/README.md +7 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/compare.c +300 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/compare.h +66 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/compare_test.cc +236 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto.c +572 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto.h +62 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_public_import_test.proto +32 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_regular_import_test.proto +36 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_test.cc +143 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_test.proto +119 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_weak_import_test.proto +28 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/def_to_proto_wweak_import_test.proto +28 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/required_fields.c +311 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/required_fields.h +94 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/required_fields_test.cc +202 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upb/util/required_fields_test.proto +48 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upbc/BUILD +78 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upbc/common.cc +77 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upbc/common.h +112 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upbc/protoc-gen-upb.cc +1997 -0
- data/ext/ruby_memprofiler_pprof/vendor/upb/upbc/protoc-gen-upbdefs.cc +193 -0
- data/lib/ruby_memprofiler_pprof/atfork.rb +77 -0
- data/lib/ruby_memprofiler_pprof/block_flusher.rb +61 -0
- data/lib/ruby_memprofiler_pprof/file_flusher.rb +45 -0
- data/lib/ruby_memprofiler_pprof/profile_app.rb +30 -0
- data/lib/ruby_memprofiler_pprof/profile_data.rb +18 -0
- data/lib/ruby_memprofiler_pprof/version.rb +5 -0
- data/lib/ruby_memprofiler_pprof.rb +8 -0
- data/libexec/ruby_memprofiler_pprof_profile +16 -0
- metadata +257 -0
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
|
|
2
|
+
<!---
|
|
3
|
+
This document contains embedded graphviz diagrams inside ```dot blocks.
|
|
4
|
+
|
|
5
|
+
To convert it to rendered form using render.py:
|
|
6
|
+
$ ./render.py wrapping-upb.in.md
|
|
7
|
+
|
|
8
|
+
You can also live-preview this document with all diagrams using Markdown Preview Enhanced
|
|
9
|
+
in Visual Studio Code:
|
|
10
|
+
https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced
|
|
11
|
+
--->
|
|
12
|
+
|
|
13
|
+
# Building a protobuf library on upb
|
|
14
|
+
|
|
15
|
+
This is a guide for creating a new protobuf implementation based on upb. It
|
|
16
|
+
starts from the beginning and walks you through the process, highlighting
|
|
17
|
+
some important design choices you will need to make.
|
|
18
|
+
|
|
19
|
+
## Overview
|
|
20
|
+
|
|
21
|
+
A protobuf implementation consists of two main pieces:
|
|
22
|
+
|
|
23
|
+
1. a code generator, run at compile time, to turn `.proto` files into source
|
|
24
|
+
files in your language (we will call this "zlang", assuming an extension of ".z").
|
|
25
|
+
2. a runtime component, which implements the wire format and provides the data
|
|
26
|
+
structures for representing protobuf data and metadata.
|
|
27
|
+
|
|
28
|
+
<br/>
|
|
29
|
+
|
|
30
|
+
```dot {align="center"}
|
|
31
|
+
digraph {
|
|
32
|
+
rankdir=LR;
|
|
33
|
+
newrank=true;
|
|
34
|
+
node [style="rounded,filled" shape=box]
|
|
35
|
+
"foo.proto" -> protoc;
|
|
36
|
+
"foo.proto" [shape=folder];
|
|
37
|
+
protoc [fillcolor=lightgrey];
|
|
38
|
+
protoc -> "protoc-gen-zlang";
|
|
39
|
+
"protoc-gen-zlang" -> "foo.z";
|
|
40
|
+
"protoc-gen-zlang" [fillcolor=palegreen3];
|
|
41
|
+
"foo.z" [shape=folder];
|
|
42
|
+
labelloc="b";
|
|
43
|
+
label="Compile Time";
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
<br/>
|
|
48
|
+
|
|
49
|
+
```dot {align="center"}
|
|
50
|
+
digraph {
|
|
51
|
+
newrank=true;
|
|
52
|
+
node [style="rounded,filled" shape=box fillcolor=lightgrey]
|
|
53
|
+
"foo.z" -> "zlang/upb glue (FFI)";
|
|
54
|
+
"zlang/upb glue (FFI)" -> "upb (C)";
|
|
55
|
+
"zlang/upb glue (FFI)" [fillcolor=palegreen3];
|
|
56
|
+
labelloc="b";
|
|
57
|
+
label="Runtime";
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The parts in green are what you will need to implement.
|
|
62
|
+
|
|
63
|
+
Note that your code generator (`protoc-gen-zlang`) does *not* need to generate
|
|
64
|
+
any C code (eg. `foo.c`). While upb itself is written in C, upb's parsers and
|
|
65
|
+
serializers are fully table-driven, which means there is never any need or even
|
|
66
|
+
benefit to generating C code for each proto. upb is capable of full-speed
|
|
67
|
+
parsing even when schema data is loaded at runtime from strings embedded into
|
|
68
|
+
`foo.z`. This is a key benefit of upb compared with C++ protos, which have
|
|
69
|
+
traditionally relied on generated parsers in `foo.pb.cc` files to achieve full
|
|
70
|
+
parsing speed, and suffered a ~10x speed penalty in the parser when the schema
|
|
71
|
+
data was loaded at runtime.
|
|
72
|
+
|
|
73
|
+
## Prerequisites
|
|
74
|
+
|
|
75
|
+
There are a few things that the language runtime must provide in order to wrap
|
|
76
|
+
upb.
|
|
77
|
+
|
|
78
|
+
1. **FFI**: To wrap upb, your language must be able to call into a C API
|
|
79
|
+
through a Foreign Function Interface (FFI). Most languages support FFI in
|
|
80
|
+
some form, either through "native extensions" (in which you write some C
|
|
81
|
+
code to implement new methods in your language) or through a direct FFI (in
|
|
82
|
+
which you can call into regular C functions directly from your language
|
|
83
|
+
using a special library).
|
|
84
|
+
2. **Finalizers, Destructors, or Cleaners**: The runtime must provide
|
|
85
|
+
finalizers or destructors of some sort. There must be a way of triggering a
|
|
86
|
+
call to a C function when the language garbage collects or otherwise
|
|
87
|
+
destroys an object. We don't care much whether it is a finalizer, a
|
|
88
|
+
destructor, or a cleaner, as long as it gets called eventually when the
|
|
89
|
+
object is destroyed. upb allocates memory in C space, and a finalizer is our
|
|
90
|
+
only way of making sure that memory is freed and does not leak.
|
|
91
|
+
3. **HashMap with weak values**: (optional) This is not a strong requirement,
|
|
92
|
+
but it is sometimes helpful to have a global hashmap with weak values to act
|
|
93
|
+
as a `upb_msg* -> wrapper` object cache. We want the values to be weak (not
|
|
94
|
+
the keys). There is some question about whether we want to continue to use
|
|
95
|
+
this pattern going forward.
|
|
96
|
+
|
|
97
|
+
## Reflection vs. MiniTables
|
|
98
|
+
|
|
99
|
+
The first key design decision you will need to make is whether your generated
|
|
100
|
+
code will access message data via reflection or minitables. Generally more
|
|
101
|
+
dynamic languages will want to use reflection and more static languages will
|
|
102
|
+
want to use minitables.
|
|
103
|
+
|
|
104
|
+
### Reflection
|
|
105
|
+
|
|
106
|
+
Reflection-based data access makes the most sense in highly dynamic language
|
|
107
|
+
interpreters, where method dispatch is generally resolved via strings and hash
|
|
108
|
+
table lookups.
|
|
109
|
+
|
|
110
|
+
In such languages, you can often implement a special method like `__getattr__`
|
|
111
|
+
(Python) or `method_missing` (Ruby) that receives the method name as a string.
|
|
112
|
+
Using upb's reflection, you can look up a field name using the method name,
|
|
113
|
+
thereby using a hash table belonging to upb instead of one provided by the
|
|
114
|
+
language.
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
class FooMessage:
|
|
118
|
+
# Written in Python for illustration, but in practice we will want to
|
|
119
|
+
# implement this in C for speed.
|
|
120
|
+
def __getattr__(self, name):
|
|
121
|
+
field = FooMessage.descriptor.fields_by_name[name]
|
|
122
|
+
return field.get_value(self)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Using this design, we only need to attach a single `__getattr__` method to each
|
|
126
|
+
message class, instead of defining a getter/setter for each field. In this way
|
|
127
|
+
we can avoid duplicating hash tables between upb and the language interpreter,
|
|
128
|
+
reducing memory usage.
|
|
129
|
+
|
|
130
|
+
Reflection-based access requires loading full reflection at runtime. Your
|
|
131
|
+
generated code will need to embed serialized descriptors (ie. a serialized
|
|
132
|
+
message of `descriptor.proto`), which has some amount of size overhead and
|
|
133
|
+
exposes all message/field names to the binary. It also forces a hash table
|
|
134
|
+
lookup in the critical path of field access. If method calls in your language
|
|
135
|
+
already have this overhead, then this is no added burden, but for statically
|
|
136
|
+
dispatched languages it would cause extra overhead.
|
|
137
|
+
|
|
138
|
+
If we take this path to its logical conclusion, all class creation can be
|
|
139
|
+
performed fully dynamically, using only a binary descriptor as input. The
|
|
140
|
+
"generated code" becomes little more than an embedded descriptor plus a
|
|
141
|
+
library call to load it. Python has recently gone down this path. Generated
|
|
142
|
+
code now looks something like this:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
# main_pb2.py
|
|
146
|
+
from google3.net.proto2.python.internal import builder as _builder
|
|
147
|
+
from google3.net.proto2.python.public import descriptor_pool as _descriptor_pool
|
|
148
|
+
|
|
149
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile("<...>")
|
|
150
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
|
151
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google3.main_pb2', globals())
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
This is all the runtime needs to create all of the classes for messages defined
|
|
155
|
+
in that serialized descriptor. This code has no pretense of readability, but
|
|
156
|
+
a separate `.pyi` stub file provides a fully expanded and readable list of all
|
|
157
|
+
methods a user can expect to be available:
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
# main_pb2.pyi
|
|
161
|
+
from google3.net.proto2.python.public import descriptor as _descriptor
|
|
162
|
+
from google3.net.proto2.python.public import message as _message
|
|
163
|
+
from typing import ClassVar as _ClassVar, Optional as _Optional
|
|
164
|
+
|
|
165
|
+
DESCRIPTOR: _descriptor.FileDescriptor
|
|
166
|
+
|
|
167
|
+
class MyMessage(_message.Message):
|
|
168
|
+
__slots__ = ["my_field"]
|
|
169
|
+
MY_FIELD_FIELD_NUMBER: _ClassVar[int]
|
|
170
|
+
my_field: str
|
|
171
|
+
def __init__(self, my_field: _Optional[str] = ...) -> None: ...
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
To use reflection-based access:
|
|
175
|
+
|
|
176
|
+
1. Load and access descriptor data using the interfaces in google3/third_party/upb/upb/def.h.
|
|
177
|
+
2. Access message data using the interfaces in google3/third_party/upb/upb/reflection.h.
|
|
178
|
+
|
|
179
|
+
### MiniTables
|
|
180
|
+
|
|
181
|
+
MiniTables are a "lite" schema representation that are much smaller that
|
|
182
|
+
reflection. MiniTables omit names, options, and almost everything else from the
|
|
183
|
+
`.proto` file, retaining only enough information to parse and serialize binary
|
|
184
|
+
format.
|
|
185
|
+
|
|
186
|
+
MiniTables can be loaded into upb through *MiniDescriptors*. MiniDescriptors are
|
|
187
|
+
a byte-oriented format that can be embedded into your generated code and passed
|
|
188
|
+
to upb to construct MiniTables. MiniDescriptors only use printable characters,
|
|
189
|
+
and therefore do not require escaping when embedding them into generated code
|
|
190
|
+
strings. Overall the size savings of MiniDescriptors are ~60x compared with
|
|
191
|
+
regular descriptors.
|
|
192
|
+
|
|
193
|
+
MiniTables and MiniDescriptors are a natural choice for compiled languages that
|
|
194
|
+
resolve method calls at compile time. For languages that are sometimes compiled
|
|
195
|
+
and sometimes interpreted, there might not be an obvious choice. When a method
|
|
196
|
+
call is statically bound, we want to remove as much overhead as possible,
|
|
197
|
+
especially from accessors. In the extreme case, we can use unsafe APIs to read
|
|
198
|
+
raw memory at a known offset:
|
|
199
|
+
|
|
200
|
+
```java
|
|
201
|
+
// Example of a maximally-optimized generated accessor.
|
|
202
|
+
class FooMessage {
|
|
203
|
+
public long getBarField() {
|
|
204
|
+
// Using Unsafe should give us performance that is comparable to a
|
|
205
|
+
// native member access.
|
|
206
|
+
//
|
|
207
|
+
// The constant "24" is obtained from upb at compile time.
|
|
208
|
+
sun.misc.Unsafe.getLong(this.ptr, 24);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
This design is very low-level, and tightly couples the generated code to one
|
|
214
|
+
specific version of the schema and compiler. A slower but safer version would
|
|
215
|
+
look up a field by field number:
|
|
216
|
+
|
|
217
|
+
```java
|
|
218
|
+
// Example of a more loosely-coupled accessor.
|
|
219
|
+
class FooMessage {
|
|
220
|
+
public long getBarField() {
|
|
221
|
+
// The constant "2" is the field number. Internally this will look
|
|
222
|
+
// up the number "2" in the MiniTable and use that to read the value
|
|
223
|
+
// from the message.
|
|
224
|
+
upb.glue.getLong(this.ptr, 2);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
One downside of MiniTables is that they cannot support parsing or serializing
|
|
230
|
+
to JSON or TextFormat, because they do now know the field names. It should be
|
|
231
|
+
possible to generate reflection data "on the side", into separate generated
|
|
232
|
+
code files, so that reflection is only pulled in if it is being used. However
|
|
233
|
+
APIs to do this do not exist yet.
|
|
234
|
+
|
|
235
|
+
To use MiniTable-based access:
|
|
236
|
+
|
|
237
|
+
1. Load and access MiniDescriptors data using the interfaces in google3/third_party/upb/upb/mini_table.h.
|
|
238
|
+
2. Access message data using the interfaces in google3/third_party/upb/upb/mini_table_accessors.h.
|
|
239
|
+
|
|
240
|
+
## Memory Management
|
|
241
|
+
|
|
242
|
+
One of the core design challenges when wrapping upb is memory management. Every
|
|
243
|
+
language runtime will have some memory management system, whether it is
|
|
244
|
+
garbage collection, reference counting, manual memory management, or some hybrid
|
|
245
|
+
of these. upb is written in C and uses arenas for memory management, but upb is
|
|
246
|
+
designed to integrate with a wide variety of memory management schemes, and it
|
|
247
|
+
provides a number of tools for making this integration as smooth as possible.
|
|
248
|
+
|
|
249
|
+
### Arenas
|
|
250
|
+
|
|
251
|
+
upb defines data structures in C to represent messages, arrays (repeated
|
|
252
|
+
fields), and maps. A protobuf message is a hierarchical tree of these objects.
|
|
253
|
+
For example, a relatively simple protobuf tree might look something like this:
|
|
254
|
+
|
|
255
|
+
```dot {align="center"}
|
|
256
|
+
digraph G {
|
|
257
|
+
rankdir=LR;
|
|
258
|
+
newrank=true;
|
|
259
|
+
node [style="rounded,filled" shape=box colorscheme=accent8 fillcolor=1, ordering=out]
|
|
260
|
+
upb_msg -> upb_msg2;
|
|
261
|
+
upb_msg -> upb_array;
|
|
262
|
+
upb_msg [label="upb Message" fillcolor=1]
|
|
263
|
+
upb_msg2 [label="upb Message"];
|
|
264
|
+
upb_array [label="upb Array"]
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
All upb objects are allocated from an arena. An arena lets you allocate objects
|
|
269
|
+
individually, but you cannot free individual objects; you can only free the arena
|
|
270
|
+
as a whole. When the arena is freed, all of the individual objects allocated
|
|
271
|
+
from that arena are freed together.
|
|
272
|
+
|
|
273
|
+
```dot {align="center"}
|
|
274
|
+
digraph G {
|
|
275
|
+
rankdir=LR;
|
|
276
|
+
newrank=true;
|
|
277
|
+
subgraph cluster_0 {
|
|
278
|
+
label = "upb Arena"
|
|
279
|
+
graph[style="rounded,filled" fillcolor=gray]
|
|
280
|
+
node [style="rounded,filled" shape=box colorscheme=accent8 fillcolor=1, ordering=out]
|
|
281
|
+
upb_msg -> upb_array;
|
|
282
|
+
upb_msg -> upb_msg2;
|
|
283
|
+
upb_msg [label="upb Message" fillcolor=1]
|
|
284
|
+
upb_msg2 [label="upb Message"];
|
|
285
|
+
upb_array [label="upb Array"];
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
In simple cases, the entire tree of objects will all live in a single arena.
|
|
291
|
+
This has the nice property that there cannot be any dangling pointers between
|
|
292
|
+
objects, since all objects are freed at the same time.
|
|
293
|
+
|
|
294
|
+
However upb allows you to create links between any two objects, whether or
|
|
295
|
+
not they are in the same arena. The library does not know or care what arenas
|
|
296
|
+
the objects are in when you create links between them.
|
|
297
|
+
|
|
298
|
+
```dot {align="center"}
|
|
299
|
+
digraph G {
|
|
300
|
+
rankdir=LR;
|
|
301
|
+
newrank=true;
|
|
302
|
+
subgraph cluster_0 {
|
|
303
|
+
label = "upb Arena 1"
|
|
304
|
+
graph[style="rounded,filled" fillcolor=gray]
|
|
305
|
+
node [style="rounded,filled" shape=box colorscheme=accent8 fillcolor=1, ordering=out]
|
|
306
|
+
upb_msg -> upb_array;
|
|
307
|
+
upb_msg -> upb_msg2;
|
|
308
|
+
upb_msg [label="upb Message 1" fillcolor=1]
|
|
309
|
+
upb_msg2 [label="upb Message 2"];
|
|
310
|
+
upb_array [label="upb Array"];
|
|
311
|
+
}
|
|
312
|
+
subgraph cluster_1 {
|
|
313
|
+
label = "upb Arena 2"
|
|
314
|
+
graph[style="rounded,filled" fillcolor=gray]
|
|
315
|
+
node [style="rounded,filled" shape=box colorscheme=accent8 fillcolor=1]
|
|
316
|
+
upb_msg3;
|
|
317
|
+
}
|
|
318
|
+
upb_msg2 -> upb_msg3;
|
|
319
|
+
upb_msg3 [label="upb Message 3"];
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
When objects are on separate arenas, it is the user's responsibility to ensure
|
|
324
|
+
that there are no dangling pointers. In the example above, this means Arena 2
|
|
325
|
+
must outlive Message 1 and Message 2.
|
|
326
|
+
|
|
327
|
+
### Integrating GC with upb
|
|
328
|
+
|
|
329
|
+
In languages with automatic memory management, the goal is to handle all of the
|
|
330
|
+
arenas behind the scenes, so that the user does not have to manage them manually
|
|
331
|
+
or even know that they exist.
|
|
332
|
+
|
|
333
|
+
We can achieve this goal if we set up the object graph in a particular way. The
|
|
334
|
+
general strategy is to create wrapper objects around all of the C objects,
|
|
335
|
+
including the arena. Our key goal is to make sure the arena wrapper is not
|
|
336
|
+
GC'd until all of the C objects in that arena have become unreachable.
|
|
337
|
+
|
|
338
|
+
For this example, we will assume we are wrapping upb in Python:
|
|
339
|
+
|
|
340
|
+
```dot {align="center"}
|
|
341
|
+
digraph G {
|
|
342
|
+
rankdir=LR;
|
|
343
|
+
newrank=true;
|
|
344
|
+
compound=true;
|
|
345
|
+
|
|
346
|
+
subgraph cluster_1 {
|
|
347
|
+
label = "upb Arena"
|
|
348
|
+
graph[style="rounded,filled" fillcolor=gray]
|
|
349
|
+
node [style="rounded,filled" shape=box colorscheme=accent8 fillcolor=1, ordering=out]
|
|
350
|
+
upb_msg -> upb_array [style=dashed];
|
|
351
|
+
upb_msg -> upb_msg2 [style=dashed];
|
|
352
|
+
upb_msg [label="upb Message" fillcolor=1]
|
|
353
|
+
upb_msg2 [label="upb Message"];
|
|
354
|
+
upb_array [label="upb Array"]
|
|
355
|
+
dummy [style=invis]
|
|
356
|
+
}
|
|
357
|
+
subgraph cluster_python {
|
|
358
|
+
node [style="rounded,filled" shape=box colorscheme=accent8 fillcolor=2]
|
|
359
|
+
peripheries=0
|
|
360
|
+
py_upb_msg [label="Python Message"];
|
|
361
|
+
py_upb_msg2 [label="Python Message"];
|
|
362
|
+
py_upb_arena [label="Python Arena"];
|
|
363
|
+
}
|
|
364
|
+
py_upb_msg -> upb_msg [style=dashed];
|
|
365
|
+
py_upb_msg2->upb_msg2 [style=dashed];
|
|
366
|
+
py_upb_msg2 -> py_upb_arena [color=springgreen4];
|
|
367
|
+
py_upb_msg -> py_upb_arena [color=springgreen4];
|
|
368
|
+
py_upb_arena -> dummy [lhead=cluster_1, color=red];
|
|
369
|
+
{
|
|
370
|
+
rank=same;
|
|
371
|
+
upb_msg;
|
|
372
|
+
py_upb_msg;
|
|
373
|
+
}
|
|
374
|
+
{
|
|
375
|
+
rank=same;
|
|
376
|
+
upb_array;
|
|
377
|
+
upb_msg2;
|
|
378
|
+
py_upb_msg2;
|
|
379
|
+
}
|
|
380
|
+
{ rank=same;
|
|
381
|
+
dummy;
|
|
382
|
+
py_upb_arena;
|
|
383
|
+
}
|
|
384
|
+
dummy->upb_array [style=invis];
|
|
385
|
+
dummy->upb_msg2 [style=invis];
|
|
386
|
+
|
|
387
|
+
subgraph cluster_01 {
|
|
388
|
+
node [shape=plaintext]
|
|
389
|
+
peripheries=0
|
|
390
|
+
key [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
|
|
391
|
+
<tr><td align="right" port="i1">raw ptr</td></tr>
|
|
392
|
+
<tr><td align="right" port="i2">unique ptr</td></tr>
|
|
393
|
+
<tr><td align="right" port="i3">shared (GC) ptr</td></tr>
|
|
394
|
+
</table>>]
|
|
395
|
+
key2 [label=<<table border="0" cellpadding="2" cellspacing="0" cellborder="0">
|
|
396
|
+
<tr><td port="i1"> </td></tr>
|
|
397
|
+
<tr><td port="i2"> </td></tr>
|
|
398
|
+
<tr><td port="i3"> </td></tr>
|
|
399
|
+
</table>>]
|
|
400
|
+
key:i1:e -> key2:i1:w [style=dashed]
|
|
401
|
+
key:i2:e -> key2:i2:w [color=red]
|
|
402
|
+
key:i3:e -> key2:i3:w [color=springgreen4]
|
|
403
|
+
}
|
|
404
|
+
key2:i1:w -> upb_msg [style=invis];
|
|
405
|
+
{
|
|
406
|
+
rank=same;
|
|
407
|
+
key;
|
|
408
|
+
upb_msg;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
In this example we have three different kinds of pointers:
|
|
414
|
+
|
|
415
|
+
* **raw ptr**: This is a pointer that carries no ownership.
|
|
416
|
+
* **unique ptr**: This is a pointer has *unique ownership* of the target. The owner
|
|
417
|
+
will free the target in its destructor (or finalizer, or cleaner). There can
|
|
418
|
+
only be a single unique pointer to a given object.
|
|
419
|
+
* **shared (GC) ptr**: This is a pointer that has *shared ownership* of the
|
|
420
|
+
target. Many objects can point to the target, and the target will be deleted
|
|
421
|
+
only when all such references are gone. In a runtime with automatic memory
|
|
422
|
+
management (GC), this is a reference that participates in GC. In Python such
|
|
423
|
+
references use reference counting, but in other VMs they may use mark and
|
|
424
|
+
sweep or some other form of GC instead.
|
|
425
|
+
|
|
426
|
+
The Python Message wrappers have only raw pointers to the underlying message,
|
|
427
|
+
but they contain a shared pointer to the arena that will ensure that the raw
|
|
428
|
+
pointer remains valid. Only when all message wrapper objects are destroyed
|
|
429
|
+
will the Python Arena become unreachable, and the upb arena ultimately freed.
|
|
430
|
+
|
|
431
|
+
### Links between arenas with "Fuse"
|
|
432
|
+
|
|
433
|
+
The design given above works well for objects that live in a single arena. But
|
|
434
|
+
what if a user wants to create a link between two objects in different arenas?
|
|
435
|
+
|
|
436
|
+
TODO
|
|
437
|
+
|
|
438
|
+
## UTF-8 vs. UTF-16
|
|
439
|
+
|
|
440
|
+
TODO
|
|
441
|
+
|
|
442
|
+
## Object Cache
|
|
443
|
+
|
|
444
|
+
TODO
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# Copyright (c) 2009-2021, Google LLC
|
|
2
|
+
# All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
|
6
|
+
# * Redistributions of source code must retain the above copyright
|
|
7
|
+
# notice, this list of conditions and the following disclaimer.
|
|
8
|
+
# * Redistributions in binary form must reproduce the above copyright
|
|
9
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
10
|
+
# documentation and/or other materials provided with the distribution.
|
|
11
|
+
# * Neither the name of Google LLC nor the
|
|
12
|
+
# names of its contributors may be used to endorse or promote products
|
|
13
|
+
# derived from this software without specific prior written permission.
|
|
14
|
+
#
|
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
16
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
17
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
18
|
+
# DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY
|
|
19
|
+
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
20
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
21
|
+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
22
|
+
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
23
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
24
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
25
|
+
|
|
26
|
+
# begin:github_only
|
|
27
|
+
load("//python:py_extension.bzl", "py_extension")
|
|
28
|
+
# end:github_only
|
|
29
|
+
|
|
30
|
+
load("@bazel_skylib//lib:selects.bzl", "selects")
|
|
31
|
+
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "string_flag")
|
|
32
|
+
load("//bazel:build_defs.bzl", "UPB_DEFAULT_COPTS")
|
|
33
|
+
|
|
34
|
+
licenses(["notice"])
|
|
35
|
+
|
|
36
|
+
package(
|
|
37
|
+
default_visibility = ["//python/dist:__pkg__"],
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
LIMITED_API_FLAG_SELECT = {
|
|
41
|
+
":limited_api_3.7": ["-DPy_LIMITED_API=0x03070000"],
|
|
42
|
+
":limited_api_3.10": ["-DPy_LIMITED_API=0x030a0000"],
|
|
43
|
+
"//conditions:default": [],
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
bool_flag(
|
|
47
|
+
name = "limited_api",
|
|
48
|
+
build_setting_default = False,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
string_flag(
|
|
52
|
+
name = "python_version",
|
|
53
|
+
build_setting_default = "system",
|
|
54
|
+
values = [
|
|
55
|
+
"system",
|
|
56
|
+
"37",
|
|
57
|
+
"38",
|
|
58
|
+
"39",
|
|
59
|
+
"310",
|
|
60
|
+
],
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
config_setting(
|
|
64
|
+
name = "limited_api_3.7",
|
|
65
|
+
flag_values = {
|
|
66
|
+
":limited_api": "True",
|
|
67
|
+
":python_version": "37",
|
|
68
|
+
},
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
config_setting(
|
|
72
|
+
name = "full_api_3.7_win32",
|
|
73
|
+
flag_values = {
|
|
74
|
+
":limited_api": "False",
|
|
75
|
+
":python_version": "37",
|
|
76
|
+
},
|
|
77
|
+
values = {"cpu": "win32"},
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
config_setting(
|
|
81
|
+
name = "full_api_3.7_win64",
|
|
82
|
+
flag_values = {
|
|
83
|
+
":limited_api": "False",
|
|
84
|
+
":python_version": "37",
|
|
85
|
+
},
|
|
86
|
+
values = {"cpu": "win64"},
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
selects.config_setting_group(
|
|
90
|
+
name = "full_api_3.7",
|
|
91
|
+
match_any = [
|
|
92
|
+
":full_api_3.7_win32",
|
|
93
|
+
":full_api_3.7_win64",
|
|
94
|
+
],
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
config_setting(
|
|
98
|
+
name = "full_api_3.8_win32",
|
|
99
|
+
flag_values = {
|
|
100
|
+
":limited_api": "False",
|
|
101
|
+
":python_version": "38",
|
|
102
|
+
},
|
|
103
|
+
values = {"cpu": "win32"},
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
config_setting(
|
|
107
|
+
name = "full_api_3.8_win64",
|
|
108
|
+
flag_values = {
|
|
109
|
+
":limited_api": "False",
|
|
110
|
+
":python_version": "38",
|
|
111
|
+
},
|
|
112
|
+
values = {"cpu": "win64"},
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
selects.config_setting_group(
|
|
116
|
+
name = "full_api_3.8",
|
|
117
|
+
match_any = [
|
|
118
|
+
":full_api_3.8_win32",
|
|
119
|
+
":full_api_3.8_win64",
|
|
120
|
+
],
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
config_setting(
|
|
124
|
+
name = "full_api_3.9_win32",
|
|
125
|
+
flag_values = {
|
|
126
|
+
":limited_api": "False",
|
|
127
|
+
":python_version": "39",
|
|
128
|
+
},
|
|
129
|
+
values = {"cpu": "win32"},
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
config_setting(
|
|
133
|
+
name = "full_api_3.9_win64",
|
|
134
|
+
flag_values = {
|
|
135
|
+
":limited_api": "False",
|
|
136
|
+
":python_version": "39",
|
|
137
|
+
},
|
|
138
|
+
values = {"cpu": "win64"},
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
selects.config_setting_group(
|
|
142
|
+
name = "full_api_3.9",
|
|
143
|
+
match_any = [
|
|
144
|
+
"full_api_3.9_win32",
|
|
145
|
+
":full_api_3.9_win64",
|
|
146
|
+
],
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
config_setting(
|
|
150
|
+
name = "limited_api_3.10_win32",
|
|
151
|
+
flag_values = {
|
|
152
|
+
":limited_api": "True",
|
|
153
|
+
":python_version": "310",
|
|
154
|
+
},
|
|
155
|
+
values = {"cpu": "win32"},
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
config_setting(
|
|
159
|
+
name = "limited_api_3.10_win64",
|
|
160
|
+
flag_values = {
|
|
161
|
+
":limited_api": "True",
|
|
162
|
+
":python_version": "310",
|
|
163
|
+
},
|
|
164
|
+
values = {"cpu": "win64"},
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
selects.config_setting_group(
|
|
168
|
+
name = "limited_api_3.10",
|
|
169
|
+
match_any = [
|
|
170
|
+
":limited_api_3.10_win32",
|
|
171
|
+
":limited_api_3.10_win64",
|
|
172
|
+
],
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
py_extension(
|
|
176
|
+
name = "_message",
|
|
177
|
+
srcs = [
|
|
178
|
+
"convert.c",
|
|
179
|
+
"convert.h",
|
|
180
|
+
"descriptor.c",
|
|
181
|
+
"descriptor.h",
|
|
182
|
+
"descriptor_containers.c",
|
|
183
|
+
"descriptor_containers.h",
|
|
184
|
+
"descriptor_pool.c",
|
|
185
|
+
"descriptor_pool.h",
|
|
186
|
+
"extension_dict.c",
|
|
187
|
+
"extension_dict.h",
|
|
188
|
+
"map.c",
|
|
189
|
+
"map.h",
|
|
190
|
+
"message.c",
|
|
191
|
+
"message.h",
|
|
192
|
+
"protobuf.c",
|
|
193
|
+
"protobuf.h",
|
|
194
|
+
"python_api.h",
|
|
195
|
+
"repeated.c",
|
|
196
|
+
"repeated.h",
|
|
197
|
+
"unknown_fields.c",
|
|
198
|
+
"unknown_fields.h",
|
|
199
|
+
],
|
|
200
|
+
copts = UPB_DEFAULT_COPTS + select(LIMITED_API_FLAG_SELECT) + [
|
|
201
|
+
# The Python API requires patterns that are ISO C incompatible, like
|
|
202
|
+
# casts between function pointers and object pointers.
|
|
203
|
+
"-Wno-pedantic",
|
|
204
|
+
],
|
|
205
|
+
deps = [
|
|
206
|
+
"//:collections",
|
|
207
|
+
"//:descriptor_upb_proto_reflection",
|
|
208
|
+
"//:reflection",
|
|
209
|
+
"//:table",
|
|
210
|
+
"//:textformat",
|
|
211
|
+
"//:upb",
|
|
212
|
+
"//upb/util:compare",
|
|
213
|
+
"//upb/util:def_to_proto",
|
|
214
|
+
"//upb/util:required_fields",
|
|
215
|
+
],
|
|
216
|
+
)
|