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,522 @@
|
|
|
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 "python/map.h"
|
|
29
|
+
|
|
30
|
+
#include "python/convert.h"
|
|
31
|
+
#include "python/message.h"
|
|
32
|
+
#include "python/protobuf.h"
|
|
33
|
+
#include "upb/collections.h"
|
|
34
|
+
|
|
35
|
+
// -----------------------------------------------------------------------------
|
|
36
|
+
// MapContainer
|
|
37
|
+
// -----------------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
typedef struct {
|
|
40
|
+
PyObject_HEAD;
|
|
41
|
+
PyObject* arena;
|
|
42
|
+
// The field descriptor (upb_FieldDef*).
|
|
43
|
+
// The low bit indicates whether the container is reified (see ptr below).
|
|
44
|
+
// - low bit set: repeated field is a stub (empty map, no underlying data).
|
|
45
|
+
// - low bit clear: repeated field is reified (points to upb_Array).
|
|
46
|
+
uintptr_t field;
|
|
47
|
+
union {
|
|
48
|
+
PyObject* parent; // stub: owning pointer to parent message.
|
|
49
|
+
upb_Map* map; // reified: the data for this array.
|
|
50
|
+
} ptr;
|
|
51
|
+
int version;
|
|
52
|
+
} PyUpb_MapContainer;
|
|
53
|
+
|
|
54
|
+
static PyObject* PyUpb_MapIterator_New(PyUpb_MapContainer* map);
|
|
55
|
+
|
|
56
|
+
static bool PyUpb_MapContainer_IsStub(PyUpb_MapContainer* self) {
|
|
57
|
+
return self->field & 1;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// If the map is reified, returns it. Otherwise, returns NULL.
|
|
61
|
+
// If NULL is returned, the object is empty and has no underlying data.
|
|
62
|
+
static upb_Map* PyUpb_MapContainer_GetIfReified(PyUpb_MapContainer* self) {
|
|
63
|
+
return PyUpb_MapContainer_IsStub(self) ? NULL : self->ptr.map;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static const upb_FieldDef* PyUpb_MapContainer_GetField(
|
|
67
|
+
PyUpb_MapContainer* self) {
|
|
68
|
+
return (const upb_FieldDef*)(self->field & ~(uintptr_t)1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static void PyUpb_MapContainer_Dealloc(void* _self) {
|
|
72
|
+
PyUpb_MapContainer* self = _self;
|
|
73
|
+
Py_DECREF(self->arena);
|
|
74
|
+
if (PyUpb_MapContainer_IsStub(self)) {
|
|
75
|
+
PyUpb_CMessage_CacheDelete(self->ptr.parent,
|
|
76
|
+
PyUpb_MapContainer_GetField(self));
|
|
77
|
+
Py_DECREF(self->ptr.parent);
|
|
78
|
+
} else {
|
|
79
|
+
PyUpb_ObjCache_Delete(self->ptr.map);
|
|
80
|
+
}
|
|
81
|
+
PyUpb_Dealloc(_self);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
PyTypeObject* PyUpb_MapContainer_GetClass(const upb_FieldDef* f) {
|
|
85
|
+
assert(upb_FieldDef_IsMap(f));
|
|
86
|
+
PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
|
|
87
|
+
return upb_FieldDef_IsSubMessage(f) ? state->message_map_container_type
|
|
88
|
+
: state->scalar_map_container_type;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
PyObject* PyUpb_MapContainer_NewStub(PyObject* parent, const upb_FieldDef* f,
|
|
92
|
+
PyObject* arena) {
|
|
93
|
+
// We only create stubs when the parent is reified, by convention. However
|
|
94
|
+
// this is not an invariant: the parent could become reified at any time.
|
|
95
|
+
assert(PyUpb_CMessage_GetIfReified(parent) == NULL);
|
|
96
|
+
PyTypeObject* cls = PyUpb_MapContainer_GetClass(f);
|
|
97
|
+
PyUpb_MapContainer* map = (void*)PyType_GenericAlloc(cls, 0);
|
|
98
|
+
map->arena = arena;
|
|
99
|
+
map->field = (uintptr_t)f | 1;
|
|
100
|
+
map->ptr.parent = parent;
|
|
101
|
+
map->version = 0;
|
|
102
|
+
Py_INCREF(arena);
|
|
103
|
+
Py_INCREF(parent);
|
|
104
|
+
return &map->ob_base;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
void PyUpb_MapContainer_Reify(PyObject* _self, upb_Map* map) {
|
|
108
|
+
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
|
|
109
|
+
if (!map) {
|
|
110
|
+
const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
|
|
111
|
+
upb_Arena* arena = PyUpb_Arena_Get(self->arena);
|
|
112
|
+
const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
|
|
113
|
+
const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
|
|
114
|
+
const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1);
|
|
115
|
+
map = upb_Map_New(arena, upb_FieldDef_CType(key_f),
|
|
116
|
+
upb_FieldDef_CType(val_f));
|
|
117
|
+
}
|
|
118
|
+
PyUpb_ObjCache_Add(map, &self->ob_base);
|
|
119
|
+
Py_DECREF(self->ptr.parent);
|
|
120
|
+
self->ptr.map = map; // Overwrites self->ptr.parent.
|
|
121
|
+
self->field &= ~(uintptr_t)1;
|
|
122
|
+
assert(!PyUpb_MapContainer_IsStub(self));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
void PyUpb_MapContainer_Invalidate(PyObject* obj) {
|
|
126
|
+
PyUpb_MapContainer* self = (PyUpb_MapContainer*)obj;
|
|
127
|
+
self->version++;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
upb_Map* PyUpb_MapContainer_EnsureReified(PyObject* _self) {
|
|
131
|
+
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
|
|
132
|
+
self->version++;
|
|
133
|
+
upb_Map* map = PyUpb_MapContainer_GetIfReified(self);
|
|
134
|
+
if (map) return map; // Already writable.
|
|
135
|
+
|
|
136
|
+
const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
|
|
137
|
+
upb_Arena* arena = PyUpb_Arena_Get(self->arena);
|
|
138
|
+
const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
|
|
139
|
+
const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
|
|
140
|
+
const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1);
|
|
141
|
+
map =
|
|
142
|
+
upb_Map_New(arena, upb_FieldDef_CType(key_f), upb_FieldDef_CType(val_f));
|
|
143
|
+
upb_MessageValue msgval = {.map_val = map};
|
|
144
|
+
PyUpb_CMessage_SetConcreteSubobj(self->ptr.parent, f, msgval);
|
|
145
|
+
PyUpb_MapContainer_Reify((PyObject*)self, map);
|
|
146
|
+
return map;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
bool PyUpb_MapContainer_Set(PyUpb_MapContainer* self, upb_Map* map,
|
|
150
|
+
upb_MessageValue key, upb_MessageValue val,
|
|
151
|
+
upb_Arena* arena) {
|
|
152
|
+
switch (upb_Map_Insert(map, key, val, arena)) {
|
|
153
|
+
case kUpb_MapInsertStatus_Inserted:
|
|
154
|
+
return true;
|
|
155
|
+
case kUpb_MapInsertStatus_Replaced:
|
|
156
|
+
// We did not insert a new key, undo the previous invalidate.
|
|
157
|
+
self->version--;
|
|
158
|
+
return true;
|
|
159
|
+
case kUpb_MapInsertStatus_OutOfMemory:
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
int PyUpb_MapContainer_AssignSubscript(PyObject* _self, PyObject* key,
|
|
165
|
+
PyObject* val) {
|
|
166
|
+
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
|
|
167
|
+
upb_Map* map = PyUpb_MapContainer_EnsureReified(_self);
|
|
168
|
+
const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
|
|
169
|
+
const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
|
|
170
|
+
const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
|
|
171
|
+
const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1);
|
|
172
|
+
upb_Arena* arena = PyUpb_Arena_Get(self->arena);
|
|
173
|
+
upb_MessageValue u_key, u_val;
|
|
174
|
+
if (!PyUpb_PyToUpb(key, key_f, &u_key, arena)) return -1;
|
|
175
|
+
|
|
176
|
+
if (val) {
|
|
177
|
+
if (!PyUpb_PyToUpb(val, val_f, &u_val, arena)) return -1;
|
|
178
|
+
if (!PyUpb_MapContainer_Set(self, map, u_key, u_val, arena)) return -1;
|
|
179
|
+
} else {
|
|
180
|
+
if (!upb_Map_Delete(map, u_key)) {
|
|
181
|
+
PyErr_Format(PyExc_KeyError, "Key not present in map");
|
|
182
|
+
return -1;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return 0;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
PyObject* PyUpb_MapContainer_Subscript(PyObject* _self, PyObject* key) {
|
|
189
|
+
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
|
|
190
|
+
upb_Map* map = PyUpb_MapContainer_GetIfReified(self);
|
|
191
|
+
const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
|
|
192
|
+
const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
|
|
193
|
+
const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
|
|
194
|
+
const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1);
|
|
195
|
+
upb_Arena* arena = PyUpb_Arena_Get(self->arena);
|
|
196
|
+
upb_MessageValue u_key, u_val;
|
|
197
|
+
if (!PyUpb_PyToUpb(key, key_f, &u_key, arena)) return NULL;
|
|
198
|
+
if (!map || !upb_Map_Get(map, u_key, &u_val)) {
|
|
199
|
+
map = PyUpb_MapContainer_EnsureReified(_self);
|
|
200
|
+
upb_Arena* arena = PyUpb_Arena_Get(self->arena);
|
|
201
|
+
if (upb_FieldDef_IsSubMessage(val_f)) {
|
|
202
|
+
u_val.msg_val = upb_Message_New(upb_FieldDef_MessageSubDef(val_f), arena);
|
|
203
|
+
} else {
|
|
204
|
+
memset(&u_val, 0, sizeof(u_val));
|
|
205
|
+
}
|
|
206
|
+
if (!PyUpb_MapContainer_Set(self, map, u_key, u_val, arena)) return false;
|
|
207
|
+
}
|
|
208
|
+
return PyUpb_UpbToPy(u_val, val_f, self->arena);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
PyObject* PyUpb_MapContainer_Contains(PyObject* _self, PyObject* key) {
|
|
212
|
+
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
|
|
213
|
+
upb_Map* map = PyUpb_MapContainer_GetIfReified(self);
|
|
214
|
+
if (!map) Py_RETURN_FALSE;
|
|
215
|
+
const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
|
|
216
|
+
const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
|
|
217
|
+
const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
|
|
218
|
+
upb_MessageValue u_key;
|
|
219
|
+
if (!PyUpb_PyToUpb(key, key_f, &u_key, NULL)) return NULL;
|
|
220
|
+
if (upb_Map_Get(map, u_key, NULL)) {
|
|
221
|
+
Py_RETURN_TRUE;
|
|
222
|
+
} else {
|
|
223
|
+
Py_RETURN_FALSE;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
PyObject* PyUpb_MapContainer_Clear(PyObject* _self, PyObject* key) {
|
|
228
|
+
upb_Map* map = PyUpb_MapContainer_EnsureReified(_self);
|
|
229
|
+
upb_Map_Clear(map);
|
|
230
|
+
Py_RETURN_NONE;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
static PyObject* PyUpb_MapContainer_Get(PyObject* _self, PyObject* args,
|
|
234
|
+
PyObject* kwargs) {
|
|
235
|
+
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
|
|
236
|
+
static const char* kwlist[] = {"key", "default", NULL};
|
|
237
|
+
PyObject* key;
|
|
238
|
+
PyObject* default_value = NULL;
|
|
239
|
+
upb_Map* map = PyUpb_MapContainer_GetIfReified(self);
|
|
240
|
+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", (char**)kwlist, &key,
|
|
241
|
+
&default_value)) {
|
|
242
|
+
return NULL;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
|
|
246
|
+
const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
|
|
247
|
+
const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
|
|
248
|
+
const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1);
|
|
249
|
+
upb_Arena* arena = PyUpb_Arena_Get(self->arena);
|
|
250
|
+
upb_MessageValue u_key, u_val;
|
|
251
|
+
if (!PyUpb_PyToUpb(key, key_f, &u_key, arena)) return NULL;
|
|
252
|
+
if (map && upb_Map_Get(map, u_key, &u_val)) {
|
|
253
|
+
return PyUpb_UpbToPy(u_val, val_f, self->arena);
|
|
254
|
+
}
|
|
255
|
+
if (default_value) {
|
|
256
|
+
Py_INCREF(default_value);
|
|
257
|
+
return default_value;
|
|
258
|
+
}
|
|
259
|
+
Py_RETURN_NONE;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
static PyObject* PyUpb_MapContainer_GetEntryClass(PyObject* _self,
|
|
263
|
+
PyObject* arg) {
|
|
264
|
+
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
|
|
265
|
+
const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
|
|
266
|
+
const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
|
|
267
|
+
return PyUpb_Descriptor_GetClass(entry_m);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
Py_ssize_t PyUpb_MapContainer_Length(PyObject* _self) {
|
|
271
|
+
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
|
|
272
|
+
upb_Map* map = PyUpb_MapContainer_GetIfReified(self);
|
|
273
|
+
return map ? upb_Map_Size(map) : 0;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
PyUpb_MapContainer* PyUpb_MapContainer_Check(PyObject* _self) {
|
|
277
|
+
PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
|
|
278
|
+
if (!PyObject_TypeCheck(_self, state->message_map_container_type) &&
|
|
279
|
+
!PyObject_TypeCheck(_self, state->scalar_map_container_type)) {
|
|
280
|
+
PyErr_Format(PyExc_TypeError, "Expected protobuf map, but got %R", _self);
|
|
281
|
+
return NULL;
|
|
282
|
+
}
|
|
283
|
+
return (PyUpb_MapContainer*)_self;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
int PyUpb_CMessage_InitMapAttributes(PyObject* map, PyObject* value,
|
|
287
|
+
const upb_FieldDef* f);
|
|
288
|
+
|
|
289
|
+
static PyObject* PyUpb_MapContainer_MergeFrom(PyObject* _self, PyObject* _arg) {
|
|
290
|
+
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
|
|
291
|
+
const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
|
|
292
|
+
|
|
293
|
+
if (PyDict_Check(_arg)) {
|
|
294
|
+
return PyErr_Format(PyExc_AttributeError, "Merging of dict is not allowed");
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (PyUpb_CMessage_InitMapAttributes(_self, _arg, f) < 0) {
|
|
298
|
+
return NULL;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
Py_RETURN_NONE;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
static PyObject* PyUpb_MapContainer_Repr(PyObject* _self) {
|
|
305
|
+
PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self;
|
|
306
|
+
upb_Map* map = PyUpb_MapContainer_GetIfReified(self);
|
|
307
|
+
PyObject* dict = PyDict_New();
|
|
308
|
+
if (map) {
|
|
309
|
+
const upb_FieldDef* f = PyUpb_MapContainer_GetField(self);
|
|
310
|
+
const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
|
|
311
|
+
const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
|
|
312
|
+
const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1);
|
|
313
|
+
size_t iter = kUpb_Map_Begin;
|
|
314
|
+
while (upb_MapIterator_Next(map, &iter)) {
|
|
315
|
+
PyObject* key =
|
|
316
|
+
PyUpb_UpbToPy(upb_MapIterator_Key(map, iter), key_f, self->arena);
|
|
317
|
+
PyObject* val =
|
|
318
|
+
PyUpb_UpbToPy(upb_MapIterator_Value(map, iter), val_f, self->arena);
|
|
319
|
+
if (!key || !val) {
|
|
320
|
+
Py_XDECREF(key);
|
|
321
|
+
Py_XDECREF(val);
|
|
322
|
+
Py_DECREF(dict);
|
|
323
|
+
return NULL;
|
|
324
|
+
}
|
|
325
|
+
PyDict_SetItem(dict, key, val);
|
|
326
|
+
Py_DECREF(key);
|
|
327
|
+
Py_DECREF(val);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
PyObject* repr = PyObject_Repr(dict);
|
|
331
|
+
Py_DECREF(dict);
|
|
332
|
+
return repr;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
PyObject* PyUpb_MapContainer_GetOrCreateWrapper(upb_Map* map,
|
|
336
|
+
const upb_FieldDef* f,
|
|
337
|
+
PyObject* arena) {
|
|
338
|
+
PyUpb_MapContainer* ret = (void*)PyUpb_ObjCache_Get(map);
|
|
339
|
+
if (ret) return &ret->ob_base;
|
|
340
|
+
|
|
341
|
+
PyTypeObject* cls = PyUpb_MapContainer_GetClass(f);
|
|
342
|
+
ret = (void*)PyType_GenericAlloc(cls, 0);
|
|
343
|
+
ret->arena = arena;
|
|
344
|
+
ret->field = (uintptr_t)f;
|
|
345
|
+
ret->ptr.map = map;
|
|
346
|
+
ret->version = 0;
|
|
347
|
+
Py_INCREF(arena);
|
|
348
|
+
PyUpb_ObjCache_Add(map, &ret->ob_base);
|
|
349
|
+
return &ret->ob_base;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// -----------------------------------------------------------------------------
|
|
353
|
+
// ScalarMapContainer
|
|
354
|
+
// -----------------------------------------------------------------------------
|
|
355
|
+
|
|
356
|
+
static PyMethodDef PyUpb_ScalarMapContainer_Methods[] = {
|
|
357
|
+
{"__contains__", PyUpb_MapContainer_Contains, METH_O,
|
|
358
|
+
"Tests whether a key is a member of the map."},
|
|
359
|
+
{"clear", PyUpb_MapContainer_Clear, METH_NOARGS,
|
|
360
|
+
"Removes all elements from the map."},
|
|
361
|
+
{"get", (PyCFunction)PyUpb_MapContainer_Get, METH_VARARGS | METH_KEYWORDS,
|
|
362
|
+
"Gets the value for the given key if present, or otherwise a default"},
|
|
363
|
+
{"GetEntryClass", PyUpb_MapContainer_GetEntryClass, METH_NOARGS,
|
|
364
|
+
"Return the class used to build Entries of (key, value) pairs."},
|
|
365
|
+
{"MergeFrom", PyUpb_MapContainer_MergeFrom, METH_O,
|
|
366
|
+
"Merges a map into the current map."},
|
|
367
|
+
/*
|
|
368
|
+
{ "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
|
|
369
|
+
"Makes a deep copy of the class." },
|
|
370
|
+
{ "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
|
|
371
|
+
"Outputs picklable representation of the repeated field." },
|
|
372
|
+
*/
|
|
373
|
+
{NULL, NULL},
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
static PyType_Slot PyUpb_ScalarMapContainer_Slots[] = {
|
|
377
|
+
{Py_tp_dealloc, PyUpb_MapContainer_Dealloc},
|
|
378
|
+
{Py_mp_length, PyUpb_MapContainer_Length},
|
|
379
|
+
{Py_mp_subscript, PyUpb_MapContainer_Subscript},
|
|
380
|
+
{Py_mp_ass_subscript, PyUpb_MapContainer_AssignSubscript},
|
|
381
|
+
{Py_tp_methods, PyUpb_ScalarMapContainer_Methods},
|
|
382
|
+
{Py_tp_iter, PyUpb_MapIterator_New},
|
|
383
|
+
{Py_tp_repr, PyUpb_MapContainer_Repr},
|
|
384
|
+
{Py_tp_hash, PyObject_HashNotImplemented},
|
|
385
|
+
{0, NULL},
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
static PyType_Spec PyUpb_ScalarMapContainer_Spec = {
|
|
389
|
+
PYUPB_MODULE_NAME ".ScalarMapContainer",
|
|
390
|
+
sizeof(PyUpb_MapContainer),
|
|
391
|
+
0,
|
|
392
|
+
Py_TPFLAGS_DEFAULT,
|
|
393
|
+
PyUpb_ScalarMapContainer_Slots,
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
// -----------------------------------------------------------------------------
|
|
397
|
+
// MessageMapContainer
|
|
398
|
+
// -----------------------------------------------------------------------------
|
|
399
|
+
|
|
400
|
+
static PyMethodDef PyUpb_MessageMapContainer_Methods[] = {
|
|
401
|
+
{"__contains__", PyUpb_MapContainer_Contains, METH_O,
|
|
402
|
+
"Tests whether the map contains this element."},
|
|
403
|
+
{"clear", PyUpb_MapContainer_Clear, METH_NOARGS,
|
|
404
|
+
"Removes all elements from the map."},
|
|
405
|
+
{"get", (PyCFunction)PyUpb_MapContainer_Get, METH_VARARGS | METH_KEYWORDS,
|
|
406
|
+
"Gets the value for the given key if present, or otherwise a default"},
|
|
407
|
+
{"get_or_create", PyUpb_MapContainer_Subscript, METH_O,
|
|
408
|
+
"Alias for getitem, useful to make explicit that the map is mutated."},
|
|
409
|
+
{"GetEntryClass", PyUpb_MapContainer_GetEntryClass, METH_NOARGS,
|
|
410
|
+
"Return the class used to build Entries of (key, value) pairs."},
|
|
411
|
+
{"MergeFrom", PyUpb_MapContainer_MergeFrom, METH_O,
|
|
412
|
+
"Merges a map into the current map."},
|
|
413
|
+
/*
|
|
414
|
+
{ "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
|
|
415
|
+
"Makes a deep copy of the class." },
|
|
416
|
+
{ "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
|
|
417
|
+
"Outputs picklable representation of the repeated field." },
|
|
418
|
+
*/
|
|
419
|
+
{NULL, NULL},
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
static PyType_Slot PyUpb_MessageMapContainer_Slots[] = {
|
|
423
|
+
{Py_tp_dealloc, PyUpb_MapContainer_Dealloc},
|
|
424
|
+
{Py_mp_length, PyUpb_MapContainer_Length},
|
|
425
|
+
{Py_mp_subscript, PyUpb_MapContainer_Subscript},
|
|
426
|
+
{Py_mp_ass_subscript, PyUpb_MapContainer_AssignSubscript},
|
|
427
|
+
{Py_tp_methods, PyUpb_MessageMapContainer_Methods},
|
|
428
|
+
{Py_tp_iter, PyUpb_MapIterator_New},
|
|
429
|
+
{Py_tp_repr, PyUpb_MapContainer_Repr},
|
|
430
|
+
{Py_tp_hash, PyObject_HashNotImplemented},
|
|
431
|
+
{0, NULL}};
|
|
432
|
+
|
|
433
|
+
static PyType_Spec PyUpb_MessageMapContainer_Spec = {
|
|
434
|
+
PYUPB_MODULE_NAME ".MessageMapContainer", sizeof(PyUpb_MapContainer), 0,
|
|
435
|
+
Py_TPFLAGS_DEFAULT, PyUpb_MessageMapContainer_Slots};
|
|
436
|
+
|
|
437
|
+
// -----------------------------------------------------------------------------
|
|
438
|
+
// MapIterator
|
|
439
|
+
// -----------------------------------------------------------------------------
|
|
440
|
+
|
|
441
|
+
typedef struct {
|
|
442
|
+
PyObject_HEAD;
|
|
443
|
+
PyUpb_MapContainer* map; // We own a reference.
|
|
444
|
+
size_t iter;
|
|
445
|
+
int version;
|
|
446
|
+
} PyUpb_MapIterator;
|
|
447
|
+
|
|
448
|
+
static PyObject* PyUpb_MapIterator_New(PyUpb_MapContainer* map) {
|
|
449
|
+
PyUpb_ModuleState* state = PyUpb_ModuleState_Get();
|
|
450
|
+
PyUpb_MapIterator* iter =
|
|
451
|
+
(void*)PyType_GenericAlloc(state->map_iterator_type, 0);
|
|
452
|
+
iter->map = map;
|
|
453
|
+
iter->iter = kUpb_Map_Begin;
|
|
454
|
+
iter->version = map->version;
|
|
455
|
+
Py_INCREF(map);
|
|
456
|
+
return &iter->ob_base;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
static void PyUpb_MapIterator_Dealloc(void* _self) {
|
|
460
|
+
PyUpb_MapIterator* self = (PyUpb_MapIterator*)_self;
|
|
461
|
+
Py_DECREF(&self->map->ob_base);
|
|
462
|
+
PyUpb_Dealloc(_self);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
PyObject* PyUpb_MapIterator_IterNext(PyObject* _self) {
|
|
466
|
+
PyUpb_MapIterator* self = (PyUpb_MapIterator*)_self;
|
|
467
|
+
if (self->version != self->map->version) {
|
|
468
|
+
return PyErr_Format(PyExc_RuntimeError, "Map modified during iteration.");
|
|
469
|
+
}
|
|
470
|
+
upb_Map* map = PyUpb_MapContainer_GetIfReified(self->map);
|
|
471
|
+
if (!map) return NULL;
|
|
472
|
+
if (!upb_MapIterator_Next(map, &self->iter)) return NULL;
|
|
473
|
+
upb_MessageValue key = upb_MapIterator_Key(map, self->iter);
|
|
474
|
+
const upb_FieldDef* f = PyUpb_MapContainer_GetField(self->map);
|
|
475
|
+
const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f);
|
|
476
|
+
const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0);
|
|
477
|
+
return PyUpb_UpbToPy(key, key_f, self->map->arena);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
static PyType_Slot PyUpb_MapIterator_Slots[] = {
|
|
481
|
+
{Py_tp_dealloc, PyUpb_MapIterator_Dealloc},
|
|
482
|
+
{Py_tp_iter, PyObject_SelfIter},
|
|
483
|
+
{Py_tp_iternext, PyUpb_MapIterator_IterNext},
|
|
484
|
+
{0, NULL}};
|
|
485
|
+
|
|
486
|
+
static PyType_Spec PyUpb_MapIterator_Spec = {
|
|
487
|
+
PYUPB_MODULE_NAME ".MapIterator", sizeof(PyUpb_MapIterator), 0,
|
|
488
|
+
Py_TPFLAGS_DEFAULT, PyUpb_MapIterator_Slots};
|
|
489
|
+
|
|
490
|
+
// -----------------------------------------------------------------------------
|
|
491
|
+
// Top Level
|
|
492
|
+
// -----------------------------------------------------------------------------
|
|
493
|
+
|
|
494
|
+
static PyObject* GetMutableMappingBase(void) {
|
|
495
|
+
PyObject* collections = NULL;
|
|
496
|
+
PyObject* mapping = NULL;
|
|
497
|
+
PyObject* bases = NULL;
|
|
498
|
+
if ((collections = PyImport_ImportModule("collections.abc")) &&
|
|
499
|
+
(mapping = PyObject_GetAttrString(collections, "MutableMapping"))) {
|
|
500
|
+
bases = Py_BuildValue("(O)", mapping);
|
|
501
|
+
}
|
|
502
|
+
Py_XDECREF(collections);
|
|
503
|
+
Py_XDECREF(mapping);
|
|
504
|
+
return bases;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
bool PyUpb_Map_Init(PyObject* m) {
|
|
508
|
+
PyUpb_ModuleState* state = PyUpb_ModuleState_GetFromModule(m);
|
|
509
|
+
PyObject* bases = GetMutableMappingBase();
|
|
510
|
+
if (!bases) return false;
|
|
511
|
+
|
|
512
|
+
state->message_map_container_type =
|
|
513
|
+
PyUpb_AddClassWithBases(m, &PyUpb_MessageMapContainer_Spec, bases);
|
|
514
|
+
state->scalar_map_container_type =
|
|
515
|
+
PyUpb_AddClassWithBases(m, &PyUpb_ScalarMapContainer_Spec, bases);
|
|
516
|
+
state->map_iterator_type = PyUpb_AddClass(m, &PyUpb_MapIterator_Spec);
|
|
517
|
+
|
|
518
|
+
Py_DECREF(bases);
|
|
519
|
+
|
|
520
|
+
return state->message_map_container_type &&
|
|
521
|
+
state->scalar_map_container_type && state->map_iterator_type;
|
|
522
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
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
|
+
#ifndef PYUPB_MAP_H__
|
|
29
|
+
#define PYUPB_MAP_H__
|
|
30
|
+
|
|
31
|
+
#include <stdbool.h>
|
|
32
|
+
|
|
33
|
+
#include "python/python_api.h"
|
|
34
|
+
#include "upb/def.h"
|
|
35
|
+
|
|
36
|
+
// Creates a new repeated field stub for field `f` of message object `parent`.
|
|
37
|
+
// Precondition: `parent` must be a stub.
|
|
38
|
+
PyObject* PyUpb_MapContainer_NewStub(PyObject* parent, const upb_FieldDef* f,
|
|
39
|
+
PyObject* arena);
|
|
40
|
+
|
|
41
|
+
// Returns a map object wrapping `map`, of field type `f`, which must be on
|
|
42
|
+
// `arena`. If an existing wrapper object exists, it will be returned,
|
|
43
|
+
// otherwise a new object will be created. The caller always owns a ref on the
|
|
44
|
+
// returned value.
|
|
45
|
+
PyObject* PyUpb_MapContainer_GetOrCreateWrapper(upb_Map* map,
|
|
46
|
+
const upb_FieldDef* f,
|
|
47
|
+
PyObject* arena);
|
|
48
|
+
|
|
49
|
+
// Reifies a map stub to point to the concrete data in `map`.
|
|
50
|
+
// If `map` is NULL, an appropriate empty map will be constructed.
|
|
51
|
+
void PyUpb_MapContainer_Reify(PyObject* self, upb_Map* map);
|
|
52
|
+
|
|
53
|
+
// Reifies this map object if it is not already reified.
|
|
54
|
+
upb_Map* PyUpb_MapContainer_EnsureReified(PyObject* self);
|
|
55
|
+
|
|
56
|
+
// Assigns `self[key] = val` for the map `self`.
|
|
57
|
+
int PyUpb_MapContainer_AssignSubscript(PyObject* self, PyObject* key,
|
|
58
|
+
PyObject* val);
|
|
59
|
+
|
|
60
|
+
// Invalidates any existing iterators for the map `obj`.
|
|
61
|
+
void PyUpb_MapContainer_Invalidate(PyObject* obj);
|
|
62
|
+
|
|
63
|
+
// Module-level init.
|
|
64
|
+
bool PyUpb_Map_Init(PyObject* m);
|
|
65
|
+
|
|
66
|
+
#endif // PYUPB_MAP_H__
|