diff --git a/.bazelrc b/.bazelrc index eba2a89fb0..4eea8fb85c 100644 --- a/.bazelrc +++ b/.bazelrc @@ -7,7 +7,6 @@ build:opt --compilation_mode=opt build:san-common --config=dbg --strip=never --copt=-O0 --copt=-fno-omit-frame-pointer build:asan --config=san-common --copt=-fsanitize=address --linkopt=-fsanitize=address -build:asan --copt=-DADDRESS_SANITIZER=1 # ASAN hits ODR violations with shared linkage due to rules_proto. build:asan --dynamic_mode=off @@ -15,14 +14,11 @@ build:msan --config=san-common --copt=-fsanitize=memory --linkopt=-fsanitize=mem build:msan --copt=-fsanitize-memory-track-origins build:msan --copt=-fsanitize-memory-use-after-dtor build:msan --action_env=MSAN_OPTIONS=poison_in_dtor=1 -build:msan --copt=-DMEMORY_SANITIZER=1 build:tsan --config=san-common --copt=-fsanitize=thread --linkopt=-fsanitize=thread -build:tsan --copt=-DTHREAD_SANITIZER=1 build:ubsan --config=san-common --copt=-fsanitize=undefined --linkopt=-fsanitize=undefined build:ubsan --action_env=UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1 -build:ubsan --copt=-DUNDEFINED_SANITIZER=1 # Workaround for the fact that Bazel links with $CC, not $CXX # https://github.com/bazelbuild/bazel/issues/11122#issuecomment-613746748 build:ubsan --copt=-fno-sanitize=function --copt=-fno-sanitize=vptr diff --git a/.github/workflows/janitor.yml b/.github/workflows/janitor.yml index e6dcc06979..4aa88bae5f 100644 --- a/.github/workflows/janitor.yml +++ b/.github/workflows/janitor.yml @@ -28,3 +28,51 @@ jobs: echo "Closing #$pr..." gh pr close --comment "Auto-closing Copybara pull request" --delete-branch "$pr" done + + stale-others: + name: Close stale non-copybara PRs and issues + runs-on: ubuntu-latest + permissions: + issues: write # allow the action to comment on, add labels to, and close issues + pull-requests: write # allow the action to comment on, add labels to, and close PRs + steps: + - uses: actions/stale@b69b346013879cedbf50c69f572cd85439a41936 + with: + stale-issue-message: > + We triage inactive PRs and issues in order to make it easier to find + active work. If this issue should remain active or becomes active + again, please add a comment. + + + This issue is labeled `inactive` because the last activity was over + 90 days ago. + close-issue-message: > + We triage inactive PRs and issues in order to make it easier to find + active work. If this issue should remain active or becomes active + again, please reopen it. + + + This issue was closed and archived because there has been no new + activity in the 14 days since the `inactive` label was added. + stale-pr-message: > + We triage inactive PRs and issues in order to make it easier to find + active work. If this PR should remain active, please add a comment. + + + This PR is labeled `inactive` because the last activity was over 90 + days ago. This PR will be closed and archived after 14 additional + days without activity. + close-pr-message: > + We triage inactive PRs and issues in order to make it easier to find + active work. If this PR should remain active or becomes active + again, please reopen it. + + + This PR was closed and archived because there has been no new + activity in the 14 days since the `inactive` label was added. + stale-issue-label: 'inactive' + stale-pr-label: 'inactive' + exempt-issue-labels: 'help wanted' + days-before-stale: 90 + days-before-close: 14 + operations-per-run: 100 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index bf2788fe7d..22b3195649 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -32,7 +32,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86 # v2.1.2 + uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 with: results_file: results.sarif results_format: sarif diff --git a/.github/workflows/staleness_check.yml b/.github/workflows/staleness_check.yml index 2669821443..77a5e21f2c 100644 --- a/.github/workflows/staleness_check.yml +++ b/.github/workflows/staleness_check.yml @@ -54,6 +54,7 @@ jobs: credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: staleness bash: > + set -ex; if [[ -z $COMMIT_TRIGGERED_RUN || -z $MAIN_RUN ]]; then bazel query 'attr(tags, "staleness_test", //...)' | xargs bazel test $BAZEL_FLAGS || echo "Please run ./regenerate_stale_files.sh to regenerate stale files"; diff --git a/.github/workflows/staleness_refresh.yml b/.github/workflows/staleness_refresh.yml index 6f6b5ac4b5..11af94b9b6 100644 --- a/.github/workflows/staleness_refresh.yml +++ b/.github/workflows/staleness_refresh.yml @@ -30,10 +30,6 @@ jobs: # failing then you may need to generate a fresh token. token: ${{ secrets.BOT_ACCESS_TOKEN }} - name: Configure name and email address in Git - run: git config user.name "Protobuf Team Bot" && git config user.email "protobuf-team-bot@google.com" + run: cd ${{ github.workspace }} && git config user.name "Protobuf Team Bot" && git config user.email "protobuf-team-bot@google.com" - name: Commit and push update - uses: protocolbuffers/protobuf-ci/bazel@v2 - with: - credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} - bazel-cache: staleness - bash: ci/push_auto_update.sh + run: cd ${{ github.workspace }} && ./ci/push_auto_update.sh diff --git a/.github/workflows/test_cpp.yml b/.github/workflows/test_cpp.yml index 62f8296ad5..0aef03db08 100644 --- a/.github/workflows/test_cpp.yml +++ b/.github/workflows/test_cpp.yml @@ -27,14 +27,14 @@ jobs: include: # Set defaults - image: us-docker.pkg.dev/protobuf-build/containers/test/linux/sanitize@sha256:04cd765285bc52cbbf51d66c8c66d8603579cf0f19cc42df26b09d2c270541fb - - targets: //pkg/... //src/... @com_google_protobuf_examples//... + - targets: //pkg/... //src/... @com_google_protobuf_examples//... //third_party/utf8_range/... # Override cases with custom images - config: { name: "TCMalloc" } image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/tcmalloc@sha256:bd39119d74b8a3fad4ae335d4cf5294e70384676331b7e19949459fc7a8d8328" - targets: "//src/..." + targets: "//src/... //third_party/utf8_range/..." - config: { name: "aarch64" } - targets: "//src/... //src/google/protobuf/compiler:protoc_aarch64_test" + targets: "//src/... //src/google/protobuf/compiler:protoc_aarch64_test //third_party/utf8_range/..." image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/emulation:aarch64-63dd26c0c7a808d92673a3e52e848189d4ab0f17" name: Linux ${{ matrix.config.name }} runs-on: ${{ matrix.config.runner || 'ubuntu-latest' }} @@ -69,7 +69,7 @@ jobs: image: us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:${{ matrix.version }}-6.3.0-63dd26c0c7a808d92673a3e52e848189d4ab0f17 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: cpp_linux/gcc-${{ matrix.version }} - bazel: test //pkg/... //src/... @com_google_protobuf_examples//... + bazel: test //pkg/... //src/... @com_google_protobuf_examples//... //third_party/utf8_range/... linux-release: strategy: @@ -316,16 +316,16 @@ jobs: - name: MacOS os: macos-12 cache_key: macos-12 - bazel: test //src/... + bazel: test //src/... //third_party/utf8_range/... - name: MacOS Apple Silicon (build only) os: macos-12 cache_key: macos-12-arm # Current github runners are all Intel based, so just build/compile # for Apple Silicon to detect issues there. - bazel: build --cpu=darwin_arm64 //src/... + bazel: build --cpu=darwin_arm64 //src/... //third_party/utf8_range/... - name: Windows - os: windows-2019 - cache_key: windows-2019 + os: windows-2022 + cache_key: windows-2022 bazel: test //src/... @com_google_protobuf_examples//... --test_tag_filters=-conformance --build_tag_filters=-conformance name: ${{ matrix.name }} Bazel runs-on: ${{ matrix.os }} @@ -351,14 +351,6 @@ jobs: flags: -DCMAKE_CXX_STANDARD=14 cache-prefix: macos-cmake - name: Windows CMake - os: windows-2019 - flags: >- - -G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF - -Dprotobuf_BUILD_SHARED_LIBS=OFF - -Dprotobuf_BUILD_EXAMPLES=ON - vsversion: '2019' - cache-prefix: windows-2019-cmake - - name: Windows CMake 2022 os: windows-2022 flags: >- -G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF @@ -366,29 +358,39 @@ jobs: -Dprotobuf_BUILD_EXAMPLES=ON vsversion: '2022' cache-prefix: windows-2022-cmake - - name: Windows CMake 32-bit + - name: Windows CMake 2019 os: windows-2019 flags: >- -G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF + -Dprotobuf_BUILD_SHARED_LIBS=OFF + -Dprotobuf_BUILD_EXAMPLES=ON vsversion: '2019' + cache-prefix: windows-2019-cmake + # windows-2019 has python3.7 installed, which is incompatible with the latest gcloud + python-version: '3.8' + - name: Windows CMake 32-bit + os: windows-2022 + flags: >- + -G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF + vsversion: '2022' windows-arch: 'win32' - cache-prefix: windows-2019-win32-cmake + cache-prefix: windows-2022-win32-cmake - name: Windows CMake Shared - os: windows-2019 + os: windows-2022 flags: >- -G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF -Dprotobuf_BUILD_SHARED_LIBS=ON - vsversion: '2019' - cache-prefix: windows-2019-cmake + vsversion: '2022' + cache-prefix: windows-2022-cmake - name: Windows CMake Install - os: windows-2019 + os: windows-2022 install-flags: -G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF -Dprotobuf_BUILD_TESTS=OFF flags: >- -G Ninja -Dprotobuf_WITH_ZLIB=OFF -Dprotobuf_BUILD_CONFORMANCE=OFF -Dprotobuf_REMOVE_INSTALLED_HEADERS=ON -Dprotobuf_BUILD_PROTOBUF_BINARIES=OFF - vsversion: '2019' - cache-prefix: windows-2019-cmake + vsversion: '2022' + cache-prefix: windows-2022-cmake name: ${{ matrix.name }} runs-on: ${{ matrix.os }} steps: @@ -405,6 +407,17 @@ jobs: arch: ${{ matrix.windows-arch || 'x64' }} vsversion: ${{ matrix.vsversion }} + # Workaround for incompatibility between gcloud and windows-2019 runners. + - name: Install Python + if: ${{ matrix.python-version }} + uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0 + with: + python-version: ${{ matrix.python-version }} + - name: Use custom python for gcloud + if: ${{ matrix.python-version }} + run: echo "CLOUDSDK_PYTHON=${Python3_ROOT_DIR}\\python3" >> $GITHUB_ENV + shell: bash + - name: Setup sccache uses: protocolbuffers/protobuf-ci/sccache@v2 with: diff --git a/.github/workflows/test_php.yml b/.github/workflows/test_php.yml index 954aa4be8d..391442d8a2 100644 --- a/.github/workflows/test_php.yml +++ b/.github/workflows/test_php.yml @@ -150,7 +150,7 @@ jobs: strategy: fail-fast: false # Don't cancel all jobs if one fails. matrix: - version: ['8.0'] + version: ['8.2'] name: MacOS PHP ${{ matrix.version }} runs-on: macos-12 diff --git a/.github/workflows/test_python.yml b/.github/workflows/test_python.yml index e207ee3a92..a5dbe8f85b 100644 --- a/.github/workflows/test_python.yml +++ b/.github/workflows/test_python.yml @@ -17,7 +17,8 @@ jobs: fail-fast: false # Don't cancel all jobs if one fails. matrix: type: [ Pure, C++] - version: ["3.8", "3.9", "3.10", "3.11" ] + # TODO: b/309627662 - Add coverage for Python 3.12. + version: ["3.8", "3.9", "3.10", "3.11"] include: - type: Pure targets: //python/... //python:python_version_test @@ -55,7 +56,7 @@ jobs: matrix: type: [ Pure, C++] # TODO Consider expanding this set of versions. - version: [ "3.11" ] + version: [ "3.12" ] include: - type: Pure targets: //python/... //python:python_version_test @@ -76,6 +77,7 @@ jobs: with: python-version: ${{ matrix.version }} cache: pip + cache-dependency-path: 'python/requirements.txt' - name: Validate version run: python3 --version | grep ${{ matrix.version }} || (echo "Invalid Python version - $(python3 --version)" && exit 1) diff --git a/.github/workflows/test_upb.yml b/.github/workflows/test_upb.yml index 21ec308876..e819c377c3 100644 --- a/.github/workflows/test_upb.yml +++ b/.github/workflows/test_upb.yml @@ -20,6 +20,7 @@ jobs: - { name: "Fastbuild" } - { name: "Optimized", flags: "-c opt" } - { name: "FastTable", flags: "--//upb:fasttable_enabled=true" } + - { name: "FastTable ASAN", flags: "--//upb:fasttable_enabled=true --config=asan", exclude-targets: "-//benchmarks:benchmark -//python/..." } - { name: "ASAN", flags: "--config=asan -c dbg", exclude-targets: "-//benchmarks:benchmark -//python/..." } - { name: "UBSAN", flags: "--config=ubsan -c dbg", exclude-targets: "-//benchmarks:benchmark -//python/... -//lua/..." } - { name: "32-bit", flags: "--copt=-m32 --linkopt=-m32", exclude-targets: "-//benchmarks:benchmark -//python/..." } @@ -64,19 +65,23 @@ jobs: strategy: fail-fast: false # Don't cancel all jobs if one fails. name: Windows - runs-on: windows-2019 + runs-on: windows-2022 steps: - name: Checkout pending changes uses: protocolbuffers/protobuf-ci/checkout@v2 with: ref: ${{ inputs.safe-checkout }} + - uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0 + with: + cache: pip + cache-dependency-path: 'python/requirements.txt' - name: Run tests uses: protocolbuffers/protobuf-ci/bazel@v2 with: credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: "upb-bazel-windows" bazel: test --cxxopt=/std:c++17 --host_cxxopt=/std:c++17 //upb/... //upb_generator/... //python/... //protos/... //protos_generator/... - exclude-targets: -//python:conformance_test -//upb:def_builder_test + exclude-targets: -//python:conformance_test -//upb/reflection:def_builder_test macos: strategy: @@ -92,6 +97,10 @@ jobs: uses: protocolbuffers/protobuf-ci/checkout@v2 with: ref: ${{ inputs.safe-checkout }} + - uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0 + with: + cache: pip + cache-dependency-path: 'python/requirements.txt' - name: Run tests uses: protocolbuffers/protobuf-ci/bazel@v2 with: @@ -162,23 +171,24 @@ jobs: # coverage. - { os: ubuntu-latest, python-version: "3.8", architecture: x64, type: 'binary' } - { os: macos-11, python-version: "3.8", architecture: x64, type: 'binary' } - - { os: ubuntu-latest, python-version: "3.11", architecture: x64, type: 'binary' } - - { os: macos-12, python-version: "3.11", architecture: x64, type: 'binary' } + - { os: ubuntu-latest, python-version: "3.12", architecture: x64, type: 'binary' } + - { os: macos-12, python-version: "3.12", architecture: x64, type: 'binary' } - { os: ubuntu-latest, python-version: "3.8", architecture: x64, type: 'source' } - { os: macos-11, python-version: "3.8", architecture: x64, type: 'source' } - - { os: ubuntu-latest, python-version: "3.11", architecture: x64, type: 'source' } - - { os: macos-12, python-version: "3.11", architecture: x64, type: 'source' } + - { os: ubuntu-latest, python-version: "3.12", architecture: x64, type: 'source' } + - { os: macos-12, python-version: "3.12", architecture: x64, type: 'source' } - # Windows uses the full API up until Python 3.10, so each of these - # jobs tests a distinct binary wheel. + # Windows uses the full API up until Python 3.10. - { os: windows-2019, python-version: "3.8", architecture: x86, type: 'binary' } - { os: windows-2019, python-version: "3.9", architecture: x86, type: 'binary' } - { os: windows-2019, python-version: "3.10", architecture: x86, type: 'binary' } - { os: windows-2019, python-version: "3.11", architecture: x86, type: 'binary' } + - { os: windows-2019, python-version: "3.12", architecture: x86, type: 'binary' } - { os: windows-2019, python-version: "3.8", architecture: x64, type: 'binary' } - { os: windows-2019, python-version: "3.9", architecture: x64, type: 'binary' } - { os: windows-2019, python-version: "3.10", architecture: x64, type: 'binary' } - { os: windows-2019, python-version: "3.11", architecture: x64, type: 'binary' } + - { os: windows-2019, python-version: "3.12", architecture: x64, type: 'binary' } runs-on: ${{ matrix.os }} if: ${{ github.event_name != 'pull_request_target' }} defaults: @@ -195,7 +205,7 @@ jobs: with: name: requirements path: requirements - - uses: actions/setup-python@v2 + - uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0 with: python-version: ${{ matrix.python-version }} architecture: ${{ matrix.architecture }} @@ -239,7 +249,7 @@ jobs: strategy: fail-fast: false # Don't cancel all jobs if one fails. matrix: - python-version: ["3.8", "3.11"] + python-version: ["3.8", "3.12"] runs-on: ubuntu-latest if: ${{ github.event_name != 'pull_request_target' }} steps: @@ -250,7 +260,7 @@ jobs: path: wheels - name: Delete Binary Wheels run: find wheels -type f | grep -v none-any | xargs rm - - uses: actions/setup-python@v2 + - uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0 with: python-version: ${{ matrix.python-version }} - name: Setup Python venv diff --git a/BUILD.bazel b/BUILD.bazel index 5951297816..6a245bc945 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -5,7 +5,7 @@ load("@rules_java//java:defs.bzl", "java_lite_proto_library", "java_proto_librar load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain", "proto_library") load("//build_defs:cpp_opts.bzl", "COPTS", "LINK_OPTS") -load(":protobuf.bzl", "internal_objc_proto_library", "internal_php_proto_library", "internal_py_proto_library", "internal_ruby_proto_library") +load(":protobuf.bzl", "internal_objc_proto_library", "internal_php_proto_library", "internal_py_proto_library") licenses(["notice"]) @@ -150,17 +150,6 @@ filegroup( visibility = ["//visibility:public"], ) -internal_ruby_proto_library( - name = "well_known_ruby_protos", - srcs = [":well_known_protos"], - default_runtime = "", - includes = ["src"], - visibility = [ - "//conformance:__pkg__", - "//ruby:__subpackages__", - ], -) - ################################################################################ # Protocol Buffers Compiler ################################################################################ @@ -524,33 +513,6 @@ internal_php_proto_library( ], ) -internal_ruby_proto_library( - name = "test_messages_proto2_ruby_proto", - testonly = 1, - srcs = ["//src/google/protobuf:test_messages_proto2.proto"], - includes = ["src/google/protobuf"], - visibility = [ - "//conformance:__pkg__", - "//ruby:__subpackages__", - ], -) - -internal_ruby_proto_library( - name = "test_messages_proto3_ruby_proto", - testonly = 1, - srcs = ["//src/google/protobuf:test_messages_proto3.proto"], - includes = [ - "src/google/protobuf", - # The above must come first. - "src", - ], - visibility = [ - "//conformance:__pkg__", - "//ruby:__subpackages__", - ], - deps = [":well_known_ruby_protos"], -) - filegroup( name = "bzl_srcs", srcs = glob(["**/*.bzl"]), diff --git a/CMakeLists.txt b/CMakeLists.txt index ac0d03c3aa..f78fccc27a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,7 +79,7 @@ if (protobuf_BUILD_SHARED_LIBS) endif () # Version metadata -set(protobuf_VERSION_STRING "4.24.0") +set(protobuf_VERSION_STRING "4.25.0") set(protobuf_DESCRIPTION "Protocol Buffers") set(protobuf_CONTACT "protobuf@googlegroups.com") diff --git a/Protobuf-C++.podspec b/Protobuf-C++.podspec index f472aa5f1b..f2b9f35535 100644 --- a/Protobuf-C++.podspec +++ b/Protobuf-C++.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'Protobuf-C++' - s.version = '4.24.0' + s.version = '4.25.0' s.summary = 'Protocol Buffers v3 runtime library for C++.' s.homepage = 'https://github.com/google/protobuf' s.license = 'BSD-3-Clause' diff --git a/Protobuf.podspec b/Protobuf.podspec index 539394e629..0e4a664d6f 100644 --- a/Protobuf.podspec +++ b/Protobuf.podspec @@ -5,7 +5,7 @@ # dependent projects use the :git notation to refer to the library. Pod::Spec.new do |s| s.name = 'Protobuf' - s.version = '3.24.0' + s.version = '3.25.0' s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.' s.homepage = 'https://github.com/protocolbuffers/protobuf' s.license = 'BSD-3-Clause' diff --git a/WORKSPACE b/WORKSPACE index 37994f8c06..eb31a6ea40 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,5 +1,10 @@ workspace(name = "com_google_protobuf") +# An explicit self-reference to work around changes in Bazel 7.0 +# See https://github.com/bazelbuild/bazel/issues/19973#issuecomment-1787814450 +# buildifier: disable=duplicated-name +local_repository(name = "com_google_protobuf", path = ".") + load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") local_repository( @@ -12,6 +17,10 @@ load("//:protobuf_deps.bzl", "PROTOBUF_MAVEN_ARTIFACTS", "protobuf_deps") protobuf_deps() +load("@rules_python//python:repositories.bzl", "py_repositories") + +py_repositories() + # Bazel platform rules. http_archive( name = "platforms", @@ -82,6 +91,15 @@ load("@io_bazel_rules_kotlin//kotlin:core.bzl", "kt_register_toolchains") kt_register_toolchains() +http_archive( + name = "rules_ruby", + urls = [ + "https://github.com/protocolbuffers/rules_ruby/archive/b7f3e9756f3c45527be27bc38840d5a1ba690436.zip" + ], + strip_prefix = "rules_ruby-b7f3e9756f3c45527be27bc38840d5a1ba690436", + sha256 = "347927fd8de6132099fcdc58e8f7eab7bde4eb2fd424546b9cd4f1c6f8f8bad8", +) + load("@rules_ruby//ruby:defs.bzl", "ruby_runtime") ruby_runtime("system_ruby") @@ -152,21 +170,27 @@ load("@pip_deps//:requirements.bzl", "install_deps") install_deps() -load("@utf8_range//:workspace_deps.bzl", "utf8_range_deps") - -utf8_range_deps() - http_archive( name = "rules_fuzzing", - sha256 = "d9002dd3cd6437017f08593124fdd1b13b3473c7b929ceb0e60d317cb9346118", - strip_prefix = "rules_fuzzing-0.3.2", - urls = ["https://github.com/bazelbuild/rules_fuzzing/archive/v0.3.2.zip"], + sha256 = "ff52ef4845ab00e95d29c02a9e32e9eff4e0a4c9c8a6bcf8407a2f19eb3f9190", + strip_prefix = "rules_fuzzing-0.4.1", + urls = ["https://github.com/bazelbuild/rules_fuzzing/releases/download/v0.4.1/rules_fuzzing-0.4.1.zip"], + patches = ["//third_party:rules_fuzzing.patch"], + patch_args = ["-p1"], ) load("@rules_fuzzing//fuzzing:repositories.bzl", "rules_fuzzing_dependencies") rules_fuzzing_dependencies() +load("@rules_fuzzing//fuzzing:init.bzl", "rules_fuzzing_init") + +rules_fuzzing_init() + +load("@fuzzing_py_deps//:requirements.bzl", fuzzing_py_deps_install_deps = "install_deps") + +fuzzing_py_deps_install_deps() + bind( name = "python_headers", actual = "@system_python//:python_headers", diff --git a/bazel/BUILD b/bazel/BUILD index a891d615a2..be2e946f4c 100644 --- a/bazel/BUILD +++ b/bazel/BUILD @@ -7,6 +7,7 @@ load("@rules_python//python:defs.bzl", "py_binary") load("@bazel_skylib//:bzl_library.bzl", "bzl_library") +load("@bazel_skylib//lib:selects.bzl", "selects") # begin:google_only # package(default_applicable_licenses = ["//upb:license"]) @@ -14,6 +15,16 @@ load("@bazel_skylib//:bzl_library.bzl", "bzl_library") licenses(["notice"]) +# begin:google_only +# selects.config_setting_group( +# name = "android_opt", +# match_all = [ +# "//tools/cc_target_os:android", +# "//tools/compilation_mode:opt", +# ], +# ) +# end:google_only + py_binary( name = "amalgamate", srcs = ["amalgamate.py"], @@ -26,6 +37,9 @@ py_binary( bzl_library( name = "py_proto_library_bzl", srcs = ["py_proto_library.bzl"], + deps = [ + "@rules_python//python:py_info_bzl", + ], ) bzl_library( diff --git a/bazel/build_defs.bzl b/bazel/build_defs.bzl index 64c877ec3e..1ed1ffe40c 100644 --- a/bazel/build_defs.bzl +++ b/bazel/build_defs.bzl @@ -30,12 +30,20 @@ _DEFAULT_COPTS.extend([ UPB_DEFAULT_CPPOPTS = select({ "//upb:windows": [], + # begin:google_only +# # Override default -Oz for release builds on Android. +# "//bazel:android_opt": _DEFAULT_CPPOPTS + ["-O2"], + # end:google_only "//conditions:default": _DEFAULT_CPPOPTS, }) UPB_DEFAULT_COPTS = select({ "//upb:windows": [], "//upb:fasttable_enabled_setting": ["-std=gnu99", "-DUPB_ENABLE_FASTTABLE"], + # begin:google_only +# # Override default -Oz for release builds on Android. +# "//bazel:android_opt": _DEFAULT_COPTS + ["-O2"], + # end:google_only "//conditions:default": _DEFAULT_COPTS, }) diff --git a/bazel/py_proto_library.bzl b/bazel/py_proto_library.bzl index 08ff9a8f94..41c4f6c2ba 100644 --- a/bazel/py_proto_library.bzl +++ b/bazel/py_proto_library.bzl @@ -15,6 +15,7 @@ But it hasn't been deeply tested or reviewed, and upb should not be in the business of vending py_proto_library(), so we keep it private to upb. """ +load("@rules_python//python:py_info.bzl", "PyInfo") load("@bazel_skylib//lib:paths.bzl", "paths") # begin:github_only diff --git a/benchmarks/benchmark.cc b/benchmarks/benchmark.cc index a2e2cc20ea..e972b0b721 100644 --- a/benchmarks/benchmark.cc +++ b/benchmarks/benchmark.cc @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include diff --git a/benchmarks/empty.proto b/benchmarks/empty.proto index 3c32ccc38b..5374941df9 100644 --- a/benchmarks/empty.proto +++ b/benchmarks/empty.proto @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd syntax = "proto3"; diff --git a/build_defs/java_opts.bzl b/build_defs/java_opts.bzl index e9c04074ee..2da4e5f6d4 100644 --- a/build_defs/java_opts.bzl +++ b/build_defs/java_opts.bzl @@ -27,6 +27,7 @@ def protobuf_java_library(**kwargs): ) def protobuf_versioned_java_library( + automatic_module_name, bundle_description, bundle_name, bundle_symbolic_name, @@ -44,6 +45,9 @@ def protobuf_versioned_java_library( Args: bundle_description: (required) The Bundle-Description header defines a short description of this bundle. + automatic_module_name: (required) The Automatic-Module-Name header that represents + the name of the module when this bundle is used as an automatic + module. bundle_name: (required) The Bundle-Name header defines a readable name for this bundle. This should be a short, human-readable name that can contain spaces. @@ -65,6 +69,7 @@ def protobuf_versioned_java_library( """ osgi_java_library( javacopts = JAVA_OPTS, + automatic_module_name = automatic_module_name, bundle_doc_url = BUNDLE_DOC_URL, bundle_license = BUNDLE_LICENSE, bundle_version = PROTOBUF_JAVA_VERSION, diff --git a/ci/common.bazelrc b/ci/common.bazelrc index e5345cfd69..12445ba717 100644 --- a/ci/common.bazelrc +++ b/ci/common.bazelrc @@ -1,6 +1,3 @@ -# Fail if a glob doesn't match anything (https://github.com/bazelbuild/bazel/issues/8195) -build --incompatible_disallow_empty_glob - build:dbg --compilation_mode=dbg build:opt --compilation_mode=opt @@ -8,7 +5,6 @@ build:opt --compilation_mode=opt build:san-common --config=dbg --strip=never --copt=-O0 --copt=-fno-omit-frame-pointer build:asan --config=san-common --copt=-fsanitize=address --linkopt=-fsanitize=address -build:asan --copt=-DADDRESS_SANITIZER=1 # ASAN hits ODR violations with shared linkage due to rules_proto. build:asan --dynamic_mode=off @@ -16,7 +12,6 @@ build:msan --config=san-common --copt=-fsanitize=memory --linkopt=-fsanitize=mem build:msan --copt=-fsanitize-memory-track-origins build:msan --copt=-fsanitize-memory-use-after-dtor build:msan --action_env=MSAN_OPTIONS=poison_in_dtor=1 -build:msan --copt=-DMEMORY_SANITIZER=1 # Use our instrumented LLVM libc++ in Kokoro. build:docker-msan --config=msan @@ -26,11 +21,48 @@ build:docker-msan --cxxopt=-stdlib=libc++ --linkopt=-stdlib=libc++ build:tsan --config=san-common --copt=-fsanitize=thread --linkopt=-fsanitize=thread -build:tsan --copt=-DTHREAD_SANITIZER=1 build:ubsan --config=san-common --copt=-fsanitize=undefined --linkopt=-fsanitize=undefined build:ubsan --action_env=UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1 -build:ubsan --copt=-DUNDEFINED_SANITIZER=1 # Workaround for the fact that Bazel links with $CC, not $CXX # https://github.com/bazelbuild/bazel/issues/11122#issuecomment-613746748 build:ubsan --copt=-fno-sanitize=function --copt=-fno-sanitize=vptr + +# Build with all --incompatible flags that we can. This helps us prepare for +# upcoming breaking changes in Bazel. This list was generated for Bazel 6 by +# running bazelisk with the --migrate flag and filtering out all flags that +# default to true or are deprecated. +build --incompatible_check_sharding_support +build --incompatible_default_to_explicit_init_py +build --incompatible_disable_native_android_rules +build --incompatible_disable_runtimes_filegroups +build --incompatible_disable_target_provider_fields +build --incompatible_disallow_empty_glob +build --incompatible_dont_use_javasourceinfoprovider +build --incompatible_enable_android_toolchain_resolution +build --incompatible_enable_apple_toolchain_resolution +build --incompatible_exclusive_test_sandboxed +build --incompatible_remote_output_paths_relative_to_input_root +build --incompatible_remote_use_new_exit_code_for_lost_inputs +build --incompatible_sandbox_hermetic_tmp +build --incompatible_struct_has_no_methods +build --incompatible_top_level_aspects_require_providers +build --incompatible_use_cc_configure_from_rules_cc +build --incompatible_use_host_features + +# We cannot yet build successfully with the following flags: +# --incompatible_check_testonly_for_output_files +# --incompatible_config_setting_private_default_visibility +# --incompatible_disable_starlark_host_transitions +# --incompatible_disallow_struct_provider_syntax +# --incompatible_no_implicit_file_export +# --incompatible_no_rule_outputs_param +# --incompatible_stop_exporting_language_modules +# --incompatible_strict_action_env +# --incompatible_visibility_private_attributes_at_definition + +# We might be compatible with these flags, but they are not available in all +# Bazel versions we are currently using: +# --incompatible_disable_objc_library_transition +# --incompatible_fail_on_unknown_attributes +# --incompatible_merge_fixed_and_default_shell_env diff --git a/cmake/abseil-cpp.cmake b/cmake/abseil-cpp.cmake index b50fb89e6c..a4e9d2295e 100644 --- a/cmake/abseil-cpp.cmake +++ b/cmake/abseil-cpp.cmake @@ -72,6 +72,7 @@ else() absl::flat_hash_set absl::function_ref absl::hash + absl::if_constexpr absl::layout absl::log_initialize absl::log_severity diff --git a/cmake/install.cmake b/cmake/install.cmake index 998c2e31af..9679d5b267 100644 --- a/cmake/install.cmake +++ b/cmake/install.cmake @@ -78,7 +78,10 @@ foreach(_header ${protobuf_HEADERS}) elseif (_find_nosrc GREATER -1) set(_from_dir "${protobuf_SOURCE_DIR}") endif() - string(REPLACE "${_from_dir}" "" _header ${_header}) + # On some platforms `_form_dir` ends up being just "protobuf", which can + # easily match multiple times in our paths. We force it to only replace + # prefixes to avoid this case. + string(REGEX REPLACE "^${_from_dir}" "" _header ${_header}) get_filename_component(_extract_from "${_from_dir}/${_header}" ABSOLUTE) get_filename_component(_extract_name ${_header} NAME) get_filename_component(_extract_to "${CMAKE_INSTALL_INCLUDEDIR}/${_header}" DIRECTORY) diff --git a/conformance/BUILD.bazel b/conformance/BUILD.bazel index e54eab02d2..1d9ea1585c 100644 --- a/conformance/BUILD.bazel +++ b/conformance/BUILD.bazel @@ -2,7 +2,8 @@ load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_proto_library", "objc_library") load("@rules_ruby//ruby:defs.bzl", "ruby_binary") -load("//:protobuf.bzl", "internal_csharp_proto_library", "internal_objc_proto_library", "internal_php_proto_library", "internal_py_proto_library", "internal_ruby_proto_library") +load("//ruby:defs.bzl", "internal_ruby_proto_library") +load("//:protobuf.bzl", "internal_csharp_proto_library", "internal_objc_proto_library", "internal_php_proto_library", "internal_py_proto_library") load("//build_defs:internal_shell.bzl", "inline_sh_binary") load( "@rules_pkg//:mappings.bzl", @@ -22,6 +23,7 @@ exports_files([ "failure_list_php_c.txt", "failure_list_python.txt", "failure_list_python_cpp.txt", + "failure_list_python_upb.txt", "failure_list_ruby.txt", "failure_list_jruby.txt", "failure_list_jruby_ffi.txt", @@ -33,6 +35,7 @@ exports_files([ "text_format_failure_list_php_c.txt", "text_format_failure_list_python.txt", "text_format_failure_list_python_cpp.txt", + "text_format_failure_list_python_upb.txt", "text_format_failure_list_ruby.txt", "text_format_failure_list_jruby.txt", "text_format_failure_list_jruby_ffi.txt", @@ -141,7 +144,6 @@ cc_library( includes = ["."], deps = [ ":conformance_cc_proto", - "//src/google/protobuf:descriptor_legacy", "//src/google/protobuf/util:differencer", "//src/google/protobuf/util:json_util", "//src/google/protobuf/util:type_resolver_util", @@ -261,8 +263,8 @@ py_binary( deps = [ ":conformance_py_proto", "//:protobuf_python", - "//python:test_messages_proto2_py_proto", - "//python:test_messages_proto3_py_proto", + "//python:_message", # Make upb visible if we need it. + "//python:conformance_test_py_proto", ], ) @@ -326,6 +328,8 @@ objc_library( ":conformance_objc_proto", "//:test_messages_proto2_objc_proto", "//:test_messages_proto3_objc_proto", + "//src/google/protobuf/editions:test_messages_proto2_editions_objc_proto", + "//src/google/protobuf/editions:test_messages_proto3_editions_objc_proto", ], ) @@ -345,8 +349,7 @@ ruby_binary( visibility = ["//ruby:__subpackages__"], deps = [ ":conformance_ruby_proto", - "//:test_messages_proto2_ruby_proto", - "//:test_messages_proto3_ruby_proto", + "//ruby:conformance_test_ruby_proto", ], ) diff --git a/conformance/conformance_dart.dart b/conformance/conformance_dart.dart index 8491fa0827..386e63ec67 100644 --- a/conformance/conformance_dart.dart +++ b/conformance/conformance_dart.dart @@ -1,6 +1,5 @@ import 'dart:io'; -import 'package:pb_runtime/ffi/bytes.dart'; import 'package:pb_runtime/pb_runtime.dart' as pb; import 'package:third_party.protobuf/test_messages_proto2.upb.dart'; import 'package:third_party.protobuf/test_messages_proto3.upb.dart'; @@ -50,8 +49,8 @@ ConformanceResponse doTest(ConformanceRequest request) { case ConformanceRequest_payload.protobufPayload: try { testMessage = isProto3 - ? TestAllTypesProto3.fromBinary(request.protobufPayload.data) - : TestAllTypesProto2.fromBinary(request.protobufPayload.data); + ? TestAllTypesProto3.fromBinary(request.protobufPayload) + : TestAllTypesProto2.fromBinary(request.protobufPayload); } catch (e) { final parseErrorResponse = ConformanceResponse(); parseErrorResponse.parseError = '$e'; @@ -66,8 +65,7 @@ ConformanceResponse doTest(ConformanceRequest request) { switch (request.requestedOutputFormat) { case WireFormat.PROTOBUF: try { - response.protobufPayload = - Bytes(pb.GeneratedMessage.toBinary(testMessage)); + response.protobufPayload = pb.GeneratedMessage.toBinary(testMessage); } catch (e) { response.serializeError = '$e'; } diff --git a/conformance/conformance_objc.m b/conformance/conformance_objc.m index 5060ce9ecf..8a37b72bec 100644 --- a/conformance/conformance_objc.m +++ b/conformance/conformance_objc.m @@ -10,6 +10,8 @@ #import "Conformance.pbobjc.h" #import "google/protobuf/TestMessagesProto2.pbobjc.h" #import "google/protobuf/TestMessagesProto3.pbobjc.h" +#import "google/protobuf/editions/golden/TestMessagesProto2Editions.pbobjc.h" +#import "google/protobuf/editions/golden/TestMessagesProto3Editions.pbobjc.h" static void Die(NSString *format, ...) __dead2; @@ -49,22 +51,25 @@ static ConformanceResponse *DoTest(ConformanceRequest *request) { break; case ConformanceRequest_Payload_OneOfCase_ProtobufPayload: { - Class msgClass = nil; - if ([request.messageType isEqual:@"protobuf_test_messages.proto3.TestAllTypesProto3"]) { - msgClass = [Proto3TestAllTypesProto3 class]; - } else if ([request.messageType - isEqual:@"protobuf_test_messages.proto2.TestAllTypesProto2"]) { - msgClass = [Proto2TestAllTypesProto2 class]; + NSDictionary *mappings = @{ + @"protobuf_test_messages.proto2.TestAllTypesProto2" : [Proto2TestAllTypesProto2 class], + @"protobuf_test_messages.proto3.TestAllTypesProto3" : [Proto3TestAllTypesProto3 class], + @"protobuf_test_messages.editions.proto2.TestAllTypesProto2" : + [EditionsProto2TestAllTypesProto2 class], + @"protobuf_test_messages.editions.proto3.TestAllTypesProto3" : + [EditionsProto3TestAllTypesProto3 class], + }; + Class msgClass = mappings[request.messageType]; + if (msgClass) { + NSError *error = nil; + testMessage = [msgClass parseFromData:request.protobufPayload error:&error]; + if (!testMessage) { + response.parseError = [NSString stringWithFormat:@"Parse error: %@", error]; + } } else { response.runtimeError = [NSString stringWithFormat:@"Protobuf request had an unknown message_type: %@", request.messageType]; - break; - } - NSError *error = nil; - testMessage = [msgClass parseFromData:request.protobufPayload error:&error]; - if (!testMessage) { - response.parseError = [NSString stringWithFormat:@"Parse error: %@", error]; } break; } diff --git a/conformance/conformance_python.py b/conformance/conformance_python.py index 5e2a99af82..1709457a37 100755 --- a/conformance/conformance_python.py +++ b/conformance/conformance_python.py @@ -19,6 +19,8 @@ from google.protobuf import text_format from google.protobuf import test_messages_proto2_pb2 from google.protobuf import test_messages_proto3_pb2 from conformance import conformance_pb2 +from google.protobuf.editions.golden import test_messages_proto2_editions_pb2 +from google.protobuf.editions.golden import test_messages_proto3_editions_pb2 test_count = 0 verbose = False @@ -28,6 +30,18 @@ class ProtocolError(Exception): pass +def _create_test_message(type): + if type == "protobuf_test_messages.proto2.TestAllTypesProto2": + return test_messages_proto2_pb2.TestAllTypesProto2() + if type == "protobuf_test_messages.proto3.TestAllTypesProto3": + return test_messages_proto3_pb2.TestAllTypesProto3() + if type == "protobuf_test_messages.editions.proto2.TestAllTypesProto2": + return test_messages_proto2_editions_pb2.TestAllTypesProto2() + if type == "protobuf_test_messages.editions.proto3.TestAllTypesProto3": + return test_messages_proto3_editions_pb2.TestAllTypesProto3() + return None + + def do_test(request): response = conformance_pb2.ConformanceResponse() @@ -85,16 +99,12 @@ def do_test(request): response.protobuf_payload = failure_set.SerializeToString() return response - isProto3 = (request.message_type == "protobuf_test_messages.proto3.TestAllTypesProto3") isJson = (request.WhichOneof('payload') == 'json_payload') - isProto2 = (request.message_type == "protobuf_test_messages.proto2.TestAllTypesProto2") + test_message = _create_test_message(request.message_type) - if (not isProto3) and (not isJson) and (not isProto2): + if (not isJson) and (test_message is None): raise ProtocolError("Protobuf request doesn't have specific payload type") - test_message = test_messages_proto2_pb2.TestAllTypesProto2() if isProto2 else \ - test_messages_proto3_pb2.TestAllTypesProto3() - try: if request.WhichOneof('payload') == 'protobuf_payload': try: diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc index dbcaf45836..ef049c8a53 100644 --- a/conformance/conformance_test.cc +++ b/conformance/conformance_test.cc @@ -24,7 +24,6 @@ #include "absl/strings/string_view.h" #include "conformance/conformance.pb.h" #include "conformance/conformance.pb.h" -#include "google/protobuf/descriptor_legacy.h" #include "google/protobuf/message.h" #include "google/protobuf/text_format.h" @@ -143,13 +142,12 @@ ConformanceTestSuite::ConformanceRequestSetting::NewTestMessage() const { std::string ConformanceTestSuite::ConformanceRequestSetting::GetSyntaxIdentifier() const { - switch (FileDescriptorLegacy(prototype_message_.GetDescriptor()->file()) - .syntax()) { - case FileDescriptorLegacy::Syntax::SYNTAX_PROTO3: + switch (prototype_message_.GetDescriptor()->file()->edition()) { + case Edition::EDITION_PROTO3: return "Proto3"; - case FileDescriptorLegacy::Syntax::SYNTAX_PROTO2: + case Edition::EDITION_PROTO2: return "Proto2"; - case FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS: { + default: { std::string id = "Editions"; if (prototype_message_.GetDescriptor()->name() == "TestAllTypesProto2") { absl::StrAppend(&id, "_Proto2"); @@ -159,8 +157,6 @@ ConformanceTestSuite::ConformanceRequestSetting::GetSyntaxIdentifier() const { } return id; } - default: - return "Unknown"; } } diff --git a/conformance/failure_list_python.txt b/conformance/failure_list_python.txt index 8bbf094293..b278006bcc 100644 --- a/conformance/failure_list_python.txt +++ b/conformance/failure_list_python.txt @@ -1,3 +1,6 @@ Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput +Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput +Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput +Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput diff --git a/conformance/failure_list_python_cpp.txt b/conformance/failure_list_python_cpp.txt index a49939327b..9b0dea6864 100644 --- a/conformance/failure_list_python_cpp.txt +++ b/conformance/failure_list_python_cpp.txt @@ -9,3 +9,6 @@ Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput +Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput +Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput +Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput diff --git a/conformance/failure_list_python_upb.txt b/conformance/failure_list_python_upb.txt new file mode 100644 index 0000000000..b278006bcc --- /dev/null +++ b/conformance/failure_list_python_upb.txt @@ -0,0 +1,6 @@ +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput +Recommended.Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput +Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInMapValue.ProtobufOutput +Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInOptionalField.ProtobufOutput +Recommended.Editions_Proto3.JsonInput.IgnoreUnknownEnumStringValueInRepeatedField.ProtobufOutput diff --git a/conformance/text_format_failure_list_python.txt b/conformance/text_format_failure_list_python.txt index 2f7f22471c..6754aa4c4b 100644 --- a/conformance/text_format_failure_list_python.txt +++ b/conformance/text_format_failure_list_python.txt @@ -7,3 +7,9 @@ Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput +Required.Editions_Proto3.TextFormatInput.FloatFieldMaxValue.ProtobufOutput +Required.Editions_Proto3.TextFormatInput.FloatFieldMaxValue.TextFormatOutput +Required.Editions_Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput +Required.Editions_Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput +Required.Editions_Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput +Required.Editions_Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput diff --git a/conformance/text_format_failure_list_python_cpp.txt b/conformance/text_format_failure_list_python_cpp.txt index b9da32dab8..037ca00e13 100644 --- a/conformance/text_format_failure_list_python_cpp.txt +++ b/conformance/text_format_failure_list_python_cpp.txt @@ -2,3 +2,7 @@ Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput +Required.Editions_Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput +Required.Editions_Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput +Required.Editions_Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput +Required.Editions_Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput diff --git a/conformance/text_format_failure_list_python_upb.txt b/conformance/text_format_failure_list_python_upb.txt new file mode 100644 index 0000000000..377998b448 --- /dev/null +++ b/conformance/text_format_failure_list_python_upb.txt @@ -0,0 +1,11 @@ +# This is the list of text format conformance tests that are known to fail right +# now. +# TODO: These should be fixed. +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput +Required.Editions_Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput +Required.Editions_Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput +Required.Editions_Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput +Required.Editions_Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec index 2a0cf99af8..bd9a3b66db 100644 --- a/csharp/Google.Protobuf.Tools.nuspec +++ b/csharp/Google.Protobuf.Tools.nuspec @@ -5,7 +5,7 @@ Google Protocol Buffers tools Tools for Protocol Buffers - Google's data interchange format. See project site for more info. - 3.24.0 + 3.25.0 Google Inc. protobuf-packages https://github.com/protocolbuffers/protobuf/blob/main/LICENSE diff --git a/csharp/src/Google.Protobuf.Test/FieldMaskTreeTest.cs b/csharp/src/Google.Protobuf.Test/FieldMaskTreeTest.cs index 380ef72d37..d477cb35b1 100644 --- a/csharp/src/Google.Protobuf.Test/FieldMaskTreeTest.cs +++ b/csharp/src/Google.Protobuf.Test/FieldMaskTreeTest.cs @@ -406,6 +406,12 @@ namespace Google.Protobuf Merge(new FieldMaskTree().AddFieldPath("payload.single_int32"), sourceWithPayloadInt32Unset, destination, options, useDynamicMessage); Assert.IsNotNull(destination.Payload); + + // Clear unset primitive fields even if source payload is cleared + destination = source.Clone(); + Merge(new FieldMaskTree().AddFieldPath("payload.single_int32"), + clearedSource, destination, options, useDynamicMessage); + Assert.AreEqual(0, destination.Payload.SingleInt32); } [Test] diff --git a/csharp/src/Google.Protobuf.Test/testprotos.pb b/csharp/src/Google.Protobuf.Test/testprotos.pb index 9527755cf1..360fad3e66 100644 Binary files a/csharp/src/Google.Protobuf.Test/testprotos.pb and b/csharp/src/Google.Protobuf.Test/testprotos.pb differ diff --git a/csharp/src/Google.Protobuf/Compiler/Plugin.pb.cs b/csharp/src/Google.Protobuf/Compiler/Plugin.pb.cs index 82c9f82a23..cfa51a03f8 100644 --- a/csharp/src/Google.Protobuf/Compiler/Plugin.pb.cs +++ b/csharp/src/Google.Protobuf/Compiler/Plugin.pb.cs @@ -33,24 +33,25 @@ namespace Google.Protobuf.Compiler { "LnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG8SRQoXc291cmNlX2ZpbGVf", "ZGVzY3JpcHRvcnMYESADKAsyJC5nb29nbGUucHJvdG9idWYuRmlsZURlc2Ny", "aXB0b3JQcm90bxI7ChBjb21waWxlcl92ZXJzaW9uGAMgASgLMiEuZ29vZ2xl", - "LnByb3RvYnVmLmNvbXBpbGVyLlZlcnNpb24i4AIKFUNvZGVHZW5lcmF0b3JS", + "LnByb3RvYnVmLmNvbXBpbGVyLlZlcnNpb24ikgMKFUNvZGVHZW5lcmF0b3JS", "ZXNwb25zZRINCgVlcnJvchgBIAEoCRIaChJzdXBwb3J0ZWRfZmVhdHVyZXMY", - "AiABKAQSQgoEZmlsZRgPIAMoCzI0Lmdvb2dsZS5wcm90b2J1Zi5jb21waWxl", - "ci5Db2RlR2VuZXJhdG9yUmVzcG9uc2UuRmlsZRp/CgRGaWxlEgwKBG5hbWUY", - "ASABKAkSFwoPaW5zZXJ0aW9uX3BvaW50GAIgASgJEg8KB2NvbnRlbnQYDyAB", - "KAkSPwoTZ2VuZXJhdGVkX2NvZGVfaW5mbxgQIAEoCzIiLmdvb2dsZS5wcm90", - "b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mbyJXCgdGZWF0dXJlEhAKDEZFQVRVUkVf", - "Tk9ORRAAEhsKF0ZFQVRVUkVfUFJPVE8zX09QVElPTkFMEAESHQoZRkVBVFVS", - "RV9TVVBQT1JUU19FRElUSU9OUxACQnIKHGNvbS5nb29nbGUucHJvdG9idWYu", - "Y29tcGlsZXJCDFBsdWdpblByb3Rvc1opZ29vZ2xlLmdvbGFuZy5vcmcvcHJv", - "dG9idWYvdHlwZXMvcGx1Z2lucGKqAhhHb29nbGUuUHJvdG9idWYuQ29tcGls", - "ZXI=")); + "AiABKAQSFwoPbWluaW11bV9lZGl0aW9uGAMgASgFEhcKD21heGltdW1fZWRp", + "dGlvbhgEIAEoBRJCCgRmaWxlGA8gAygLMjQuZ29vZ2xlLnByb3RvYnVmLmNv", + "bXBpbGVyLkNvZGVHZW5lcmF0b3JSZXNwb25zZS5GaWxlGn8KBEZpbGUSDAoE", + "bmFtZRgBIAEoCRIXCg9pbnNlcnRpb25fcG9pbnQYAiABKAkSDwoHY29udGVu", + "dBgPIAEoCRI/ChNnZW5lcmF0ZWRfY29kZV9pbmZvGBAgASgLMiIuZ29vZ2xl", + "LnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvIlcKB0ZlYXR1cmUSEAoMRkVB", + "VFVSRV9OT05FEAASGwoXRkVBVFVSRV9QUk9UTzNfT1BUSU9OQUwQARIdChlG", + "RUFUVVJFX1NVUFBPUlRTX0VESVRJT05TEAJCcgocY29tLmdvb2dsZS5wcm90", + "b2J1Zi5jb21waWxlckIMUGx1Z2luUHJvdG9zWilnb29nbGUuZ29sYW5nLm9y", + "Zy9wcm90b2J1Zi90eXBlcy9wbHVnaW5wYqoCGEdvb2dsZS5Qcm90b2J1Zi5D", + "b21waWxlcg==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Compiler.Version), global::Google.Protobuf.Compiler.Version.Parser, new[]{ "Major", "Minor", "Patch", "Suffix" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Compiler.CodeGeneratorRequest), global::Google.Protobuf.Compiler.CodeGeneratorRequest.Parser, new[]{ "FileToGenerate", "Parameter", "ProtoFile", "SourceFileDescriptors", "CompilerVersion" }, null, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Compiler.CodeGeneratorResponse), global::Google.Protobuf.Compiler.CodeGeneratorResponse.Parser, new[]{ "Error", "SupportedFeatures", "File" }, null, new[]{ typeof(global::Google.Protobuf.Compiler.CodeGeneratorResponse.Types.Feature) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Compiler.CodeGeneratorResponse.Types.File), global::Google.Protobuf.Compiler.CodeGeneratorResponse.Types.File.Parser, new[]{ "Name", "InsertionPoint", "Content", "GeneratedCodeInfo" }, null, null, null, null)}) + new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Compiler.CodeGeneratorResponse), global::Google.Protobuf.Compiler.CodeGeneratorResponse.Parser, new[]{ "Error", "SupportedFeatures", "MinimumEdition", "MaximumEdition", "File" }, null, new[]{ typeof(global::Google.Protobuf.Compiler.CodeGeneratorResponse.Types.Feature) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Compiler.CodeGeneratorResponse.Types.File), global::Google.Protobuf.Compiler.CodeGeneratorResponse.Types.File.Parser, new[]{ "Name", "InsertionPoint", "Content", "GeneratedCodeInfo" }, null, null, null, null)}) })); } #endregion @@ -836,6 +837,8 @@ namespace Google.Protobuf.Compiler { _hasBits0 = other._hasBits0; error_ = other.error_; supportedFeatures_ = other.supportedFeatures_; + minimumEdition_ = other.minimumEdition_; + maximumEdition_ = other.maximumEdition_; file_ = other.file_.Clone(); _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); } @@ -913,6 +916,72 @@ namespace Google.Protobuf.Compiler { _hasBits0 &= ~1; } + /// Field number for the "minimum_edition" field. + public const int MinimumEditionFieldNumber = 3; + private readonly static int MinimumEditionDefaultValue = 0; + + private int minimumEdition_; + /// + /// The minimum edition this plugin supports. This will be treated as an + /// Edition enum, but we want to allow unknown values. It should be specified + /// according the edition enum value, *not* the edition number. Only takes + /// effect for plugins that have FEATURE_SUPPORTS_EDITIONS set. + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int MinimumEdition { + get { if ((_hasBits0 & 2) != 0) { return minimumEdition_; } else { return MinimumEditionDefaultValue; } } + set { + _hasBits0 |= 2; + minimumEdition_ = value; + } + } + /// Gets whether the "minimum_edition" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool HasMinimumEdition { + get { return (_hasBits0 & 2) != 0; } + } + /// Clears the value of the "minimum_edition" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void ClearMinimumEdition() { + _hasBits0 &= ~2; + } + + /// Field number for the "maximum_edition" field. + public const int MaximumEditionFieldNumber = 4; + private readonly static int MaximumEditionDefaultValue = 0; + + private int maximumEdition_; + /// + /// The maximum edition this plugin supports. This will be treated as an + /// Edition enum, but we want to allow unknown values. It should be specified + /// according the edition enum value, *not* the edition number. Only takes + /// effect for plugins that have FEATURE_SUPPORTS_EDITIONS set. + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int MaximumEdition { + get { if ((_hasBits0 & 4) != 0) { return maximumEdition_; } else { return MaximumEditionDefaultValue; } } + set { + _hasBits0 |= 4; + maximumEdition_ = value; + } + } + /// Gets whether the "maximum_edition" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool HasMaximumEdition { + get { return (_hasBits0 & 4) != 0; } + } + /// Clears the value of the "maximum_edition" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void ClearMaximumEdition() { + _hasBits0 &= ~4; + } + /// Field number for the "file" field. public const int FileFieldNumber = 15; private static readonly pb::FieldCodec _repeated_file_codec @@ -941,6 +1010,8 @@ namespace Google.Protobuf.Compiler { } if (Error != other.Error) return false; if (SupportedFeatures != other.SupportedFeatures) return false; + if (MinimumEdition != other.MinimumEdition) return false; + if (MaximumEdition != other.MaximumEdition) return false; if(!file_.Equals(other.file_)) return false; return Equals(_unknownFields, other._unknownFields); } @@ -951,6 +1022,8 @@ namespace Google.Protobuf.Compiler { int hash = 1; if (HasError) hash ^= Error.GetHashCode(); if (HasSupportedFeatures) hash ^= SupportedFeatures.GetHashCode(); + if (HasMinimumEdition) hash ^= MinimumEdition.GetHashCode(); + if (HasMaximumEdition) hash ^= MaximumEdition.GetHashCode(); hash ^= file_.GetHashCode(); if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); @@ -978,6 +1051,14 @@ namespace Google.Protobuf.Compiler { output.WriteRawTag(16); output.WriteUInt64(SupportedFeatures); } + if (HasMinimumEdition) { + output.WriteRawTag(24); + output.WriteInt32(MinimumEdition); + } + if (HasMaximumEdition) { + output.WriteRawTag(32); + output.WriteInt32(MaximumEdition); + } file_.WriteTo(output, _repeated_file_codec); if (_unknownFields != null) { _unknownFields.WriteTo(output); @@ -997,6 +1078,14 @@ namespace Google.Protobuf.Compiler { output.WriteRawTag(16); output.WriteUInt64(SupportedFeatures); } + if (HasMinimumEdition) { + output.WriteRawTag(24); + output.WriteInt32(MinimumEdition); + } + if (HasMaximumEdition) { + output.WriteRawTag(32); + output.WriteInt32(MaximumEdition); + } file_.WriteTo(ref output, _repeated_file_codec); if (_unknownFields != null) { _unknownFields.WriteTo(ref output); @@ -1014,6 +1103,12 @@ namespace Google.Protobuf.Compiler { if (HasSupportedFeatures) { size += 1 + pb::CodedOutputStream.ComputeUInt64Size(SupportedFeatures); } + if (HasMinimumEdition) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(MinimumEdition); + } + if (HasMaximumEdition) { + size += 1 + pb::CodedOutputStream.ComputeInt32Size(MaximumEdition); + } size += file_.CalculateSize(_repeated_file_codec); if (_unknownFields != null) { size += _unknownFields.CalculateSize(); @@ -1033,6 +1128,12 @@ namespace Google.Protobuf.Compiler { if (other.HasSupportedFeatures) { SupportedFeatures = other.SupportedFeatures; } + if (other.HasMinimumEdition) { + MinimumEdition = other.MinimumEdition; + } + if (other.HasMaximumEdition) { + MaximumEdition = other.MaximumEdition; + } file_.Add(other.file_); _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); } @@ -1057,6 +1158,14 @@ namespace Google.Protobuf.Compiler { SupportedFeatures = input.ReadUInt64(); break; } + case 24: { + MinimumEdition = input.ReadInt32(); + break; + } + case 32: { + MaximumEdition = input.ReadInt32(); + break; + } case 122: { file_.AddEntriesFrom(input, _repeated_file_codec); break; @@ -1084,6 +1193,14 @@ namespace Google.Protobuf.Compiler { SupportedFeatures = input.ReadUInt64(); break; } + case 24: { + MinimumEdition = input.ReadInt32(); + break; + } + case 32: { + MaximumEdition = input.ReadInt32(); + break; + } case 122: { file_.AddEntriesFrom(ref input, _repeated_file_codec); break; diff --git a/csharp/src/Google.Protobuf/FieldMaskTree.cs b/csharp/src/Google.Protobuf/FieldMaskTree.cs index aaa780ba92..b8a8fff586 100644 --- a/csharp/src/Google.Protobuf/FieldMaskTree.cs +++ b/csharp/src/Google.Protobuf/FieldMaskTree.cs @@ -270,6 +270,13 @@ namespace Google.Protobuf field.Accessor.SetValue(destination, destinationField); } + if (sourceField == null) + { + // If the message field is not present in the source but is in the destination, create an empty one + // so we can properly handle child entries + sourceField = field.MessageType.Parser.CreateTemplate(); + } + var childPath = path.Length == 0 ? entry.Key : path + "." + entry.Key; Merge(entry.Value, childPath, (IMessage)sourceField, (IMessage)destinationField, options); continue; diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj index dede331228..b5731cdebb 100644 --- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj +++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj @@ -5,7 +5,7 @@ C# runtime library for Protocol Buffers - Google's data interchange format. Copyright 2015, Google Inc. Google Protocol Buffers - 3.24.0 + 3.25.0 10.0 Google Inc. netstandard1.1;netstandard2.0;net45;net50 diff --git a/csharp/src/Google.Protobuf/Reflection/Descriptor.pb.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.pb.cs index 2421d98c05..4a8def666e 100644 --- a/csharp/src/Google.Protobuf/Reflection/Descriptor.pb.cs +++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.pb.cs @@ -53,190 +53,190 @@ namespace Google.Protobuf.Reflection { "X25hbWUYCiADKAkaZQoORXh0ZW5zaW9uUmFuZ2USDQoFc3RhcnQYASABKAUS", "CwoDZW5kGAIgASgFEjcKB29wdGlvbnMYAyABKAsyJi5nb29nbGUucHJvdG9i", "dWYuRXh0ZW5zaW9uUmFuZ2VPcHRpb25zGisKDVJlc2VydmVkUmFuZ2USDQoF", - "c3RhcnQYASABKAUSCwoDZW5kGAIgASgFIuADChVFeHRlbnNpb25SYW5nZU9w", + "c3RhcnQYASABKAUSCwoDZW5kGAIgASgFIuUDChVFeHRlbnNpb25SYW5nZU9w", "dGlvbnMSQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xl", "LnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24STAoLZGVjbGFyYXRpb24Y", "AiADKAsyMi5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmFuZ2VPcHRpb25z", "LkRlY2xhcmF0aW9uQgOIAQISLQoIZmVhdHVyZXMYMiABKAsyGy5nb29nbGUu", - "cHJvdG9idWYuRmVhdHVyZVNldBJaCgx2ZXJpZmljYXRpb24YAyABKA4yOC5n", + "cHJvdG9idWYuRmVhdHVyZVNldBJfCgx2ZXJpZmljYXRpb24YAyABKA4yOC5n", "b29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmFuZ2VPcHRpb25zLlZlcmlmaWNh", - "dGlvblN0YXRlOgpVTlZFUklGSUVEGmgKC0RlY2xhcmF0aW9uEg4KBm51bWJl", - "chgBIAEoBRIRCglmdWxsX25hbWUYAiABKAkSDAoEdHlwZRgDIAEoCRIQCghy", - "ZXNlcnZlZBgFIAEoCBIQCghyZXBlYXRlZBgGIAEoCEoECAQQBSI0ChFWZXJp", - "ZmljYXRpb25TdGF0ZRIPCgtERUNMQVJBVElPThAAEg4KClVOVkVSSUZJRUQQ", - "ASoJCOgHEICAgIACItUFChRGaWVsZERlc2NyaXB0b3JQcm90bxIMCgRuYW1l", - "GAEgASgJEg4KBm51bWJlchgDIAEoBRI6CgVsYWJlbBgEIAEoDjIrLmdvb2ds", - "ZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90by5MYWJlbBI4CgR0eXBl", - "GAUgASgOMiouZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3Rv", - "LlR5cGUSEQoJdHlwZV9uYW1lGAYgASgJEhAKCGV4dGVuZGVlGAIgASgJEhUK", - "DWRlZmF1bHRfdmFsdWUYByABKAkSEwoLb25lb2ZfaW5kZXgYCSABKAUSEQoJ", - "anNvbl9uYW1lGAogASgJEi4KB29wdGlvbnMYCCABKAsyHS5nb29nbGUucHJv", - "dG9idWYuRmllbGRPcHRpb25zEhcKD3Byb3RvM19vcHRpb25hbBgRIAEoCCK2", - "AgoEVHlwZRIPCgtUWVBFX0RPVUJMRRABEg4KClRZUEVfRkxPQVQQAhIOCgpU", - "WVBFX0lOVDY0EAMSDwoLVFlQRV9VSU5UNjQQBBIOCgpUWVBFX0lOVDMyEAUS", - "EAoMVFlQRV9GSVhFRDY0EAYSEAoMVFlQRV9GSVhFRDMyEAcSDQoJVFlQRV9C", - "T09MEAgSDwoLVFlQRV9TVFJJTkcQCRIOCgpUWVBFX0dST1VQEAoSEAoMVFlQ", - "RV9NRVNTQUdFEAsSDgoKVFlQRV9CWVRFUxAMEg8KC1RZUEVfVUlOVDMyEA0S", - "DQoJVFlQRV9FTlVNEA4SEQoNVFlQRV9TRklYRUQzMhAPEhEKDVRZUEVfU0ZJ", - "WEVENjQQEBIPCgtUWVBFX1NJTlQzMhAREg8KC1RZUEVfU0lOVDY0EBIiQwoF", - "TGFiZWwSEgoOTEFCRUxfT1BUSU9OQUwQARISCg5MQUJFTF9SRVBFQVRFRBAD", - "EhIKDkxBQkVMX1JFUVVJUkVEEAIiVAoUT25lb2ZEZXNjcmlwdG9yUHJvdG8S", - "DAoEbmFtZRgBIAEoCRIuCgdvcHRpb25zGAIgASgLMh0uZ29vZ2xlLnByb3Rv", - "YnVmLk9uZW9mT3B0aW9ucyKkAgoTRW51bURlc2NyaXB0b3JQcm90bxIMCgRu", - "YW1lGAEgASgJEjgKBXZhbHVlGAIgAygLMikuZ29vZ2xlLnByb3RvYnVmLkVu", - "dW1WYWx1ZURlc2NyaXB0b3JQcm90bxItCgdvcHRpb25zGAMgASgLMhwuZ29v", - "Z2xlLnByb3RvYnVmLkVudW1PcHRpb25zEk4KDnJlc2VydmVkX3JhbmdlGAQg", - "AygLMjYuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8uRW51", - "bVJlc2VydmVkUmFuZ2USFQoNcmVzZXJ2ZWRfbmFtZRgFIAMoCRovChFFbnVt", - "UmVzZXJ2ZWRSYW5nZRINCgVzdGFydBgBIAEoBRILCgNlbmQYAiABKAUibAoY", - "RW51bVZhbHVlRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSDgoGbnVt", - "YmVyGAIgASgFEjIKB29wdGlvbnMYAyABKAsyIS5nb29nbGUucHJvdG9idWYu", - "RW51bVZhbHVlT3B0aW9ucyKQAQoWU2VydmljZURlc2NyaXB0b3JQcm90bxIM", - "CgRuYW1lGAEgASgJEjYKBm1ldGhvZBgCIAMoCzImLmdvb2dsZS5wcm90b2J1", - "Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8SMAoHb3B0aW9ucxgDIAEoCzIfLmdv", - "b2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucyLBAQoVTWV0aG9kRGVzY3Jp", - "cHRvclByb3RvEgwKBG5hbWUYASABKAkSEgoKaW5wdXRfdHlwZRgCIAEoCRIT", - "CgtvdXRwdXRfdHlwZRgDIAEoCRIvCgdvcHRpb25zGAQgASgLMh4uZ29vZ2xl", - "LnByb3RvYnVmLk1ldGhvZE9wdGlvbnMSHwoQY2xpZW50X3N0cmVhbWluZxgF", - "IAEoCDoFZmFsc2USHwoQc2VydmVyX3N0cmVhbWluZxgGIAEoCDoFZmFsc2Ui", - "1AYKC0ZpbGVPcHRpb25zEhQKDGphdmFfcGFja2FnZRgBIAEoCRIcChRqYXZh", - "X291dGVyX2NsYXNzbmFtZRgIIAEoCRIiChNqYXZhX211bHRpcGxlX2ZpbGVz", - "GAogASgIOgVmYWxzZRIpCh1qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFz", - "aBgUIAEoCEICGAESJQoWamF2YV9zdHJpbmdfY2hlY2tfdXRmOBgbIAEoCDoF", - "ZmFsc2USRgoMb3B0aW1pemVfZm9yGAkgASgOMikuZ29vZ2xlLnByb3RvYnVm", - "LkZpbGVPcHRpb25zLk9wdGltaXplTW9kZToFU1BFRUQSEgoKZ29fcGFja2Fn", - "ZRgLIAEoCRIiChNjY19nZW5lcmljX3NlcnZpY2VzGBAgASgIOgVmYWxzZRIk", - "ChVqYXZhX2dlbmVyaWNfc2VydmljZXMYESABKAg6BWZhbHNlEiIKE3B5X2dl", - "bmVyaWNfc2VydmljZXMYEiABKAg6BWZhbHNlEiMKFHBocF9nZW5lcmljX3Nl", - "cnZpY2VzGCogASgIOgVmYWxzZRIZCgpkZXByZWNhdGVkGBcgASgIOgVmYWxz", - "ZRIeChBjY19lbmFibGVfYXJlbmFzGB8gASgIOgR0cnVlEhkKEW9iamNfY2xh", - "c3NfcHJlZml4GCQgASgJEhgKEGNzaGFycF9uYW1lc3BhY2UYJSABKAkSFAoM", - "c3dpZnRfcHJlZml4GCcgASgJEhgKEHBocF9jbGFzc19wcmVmaXgYKCABKAkS", - "FQoNcGhwX25hbWVzcGFjZRgpIAEoCRIeChZwaHBfbWV0YWRhdGFfbmFtZXNw", - "YWNlGCwgASgJEhQKDHJ1YnlfcGFja2FnZRgtIAEoCRItCghmZWF0dXJlcxgy", - "IAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0EkMKFHVuaW50ZXJw", - "cmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVy", - "cHJldGVkT3B0aW9uIjoKDE9wdGltaXplTW9kZRIJCgVTUEVFRBABEg0KCUNP", - "REVfU0laRRACEhAKDExJVEVfUlVOVElNRRADKgkI6AcQgICAgAJKBAgmECci", - "5wIKDk1lc3NhZ2VPcHRpb25zEiYKF21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0", - "GAEgASgIOgVmYWxzZRIuCh9ub19zdGFuZGFyZF9kZXNjcmlwdG9yX2FjY2Vz", - "c29yGAIgASgIOgVmYWxzZRIZCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZRIR", - "CgltYXBfZW50cnkYByABKAgSMgomZGVwcmVjYXRlZF9sZWdhY3lfanNvbl9m", - "aWVsZF9jb25mbGljdHMYCyABKAhCAhgBEi0KCGZlYXR1cmVzGAwgASgLMhsu", - "Z29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQSQwoUdW5pbnRlcnByZXRlZF9v", + "dGlvblN0YXRlOgpVTlZFUklGSUVEQgOIAQIaaAoLRGVjbGFyYXRpb24SDgoG", + "bnVtYmVyGAEgASgFEhEKCWZ1bGxfbmFtZRgCIAEoCRIMCgR0eXBlGAMgASgJ", + "EhAKCHJlc2VydmVkGAUgASgIEhAKCHJlcGVhdGVkGAYgASgISgQIBBAFIjQK", + "EVZlcmlmaWNhdGlvblN0YXRlEg8KC0RFQ0xBUkFUSU9OEAASDgoKVU5WRVJJ", + "RklFRBABKgkI6AcQgICAgAIi1QUKFEZpZWxkRGVzY3JpcHRvclByb3RvEgwK", + "BG5hbWUYASABKAkSDgoGbnVtYmVyGAMgASgFEjoKBWxhYmVsGAQgASgOMisu", + "Z29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsEjgK", + "BHR5cGUYBSABKA4yKi5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9y", + "UHJvdG8uVHlwZRIRCgl0eXBlX25hbWUYBiABKAkSEAoIZXh0ZW5kZWUYAiAB", + "KAkSFQoNZGVmYXVsdF92YWx1ZRgHIAEoCRITCgtvbmVvZl9pbmRleBgJIAEo", + "BRIRCglqc29uX25hbWUYCiABKAkSLgoHb3B0aW9ucxgIIAEoCzIdLmdvb2ds", + "ZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMSFwoPcHJvdG8zX29wdGlvbmFsGBEg", + "ASgIIrYCCgRUeXBlEg8KC1RZUEVfRE9VQkxFEAESDgoKVFlQRV9GTE9BVBAC", + "Eg4KClRZUEVfSU5UNjQQAxIPCgtUWVBFX1VJTlQ2NBAEEg4KClRZUEVfSU5U", + "MzIQBRIQCgxUWVBFX0ZJWEVENjQQBhIQCgxUWVBFX0ZJWEVEMzIQBxINCglU", + "WVBFX0JPT0wQCBIPCgtUWVBFX1NUUklORxAJEg4KClRZUEVfR1JPVVAQChIQ", + "CgxUWVBFX01FU1NBR0UQCxIOCgpUWVBFX0JZVEVTEAwSDwoLVFlQRV9VSU5U", + "MzIQDRINCglUWVBFX0VOVU0QDhIRCg1UWVBFX1NGSVhFRDMyEA8SEQoNVFlQ", + "RV9TRklYRUQ2NBAQEg8KC1RZUEVfU0lOVDMyEBESDwoLVFlQRV9TSU5UNjQQ", + "EiJDCgVMYWJlbBISCg5MQUJFTF9PUFRJT05BTBABEhIKDkxBQkVMX1JFUEVB", + "VEVEEAMSEgoOTEFCRUxfUkVRVUlSRUQQAiJUChRPbmVvZkRlc2NyaXB0b3JQ", + "cm90bxIMCgRuYW1lGAEgASgJEi4KB29wdGlvbnMYAiABKAsyHS5nb29nbGUu", + "cHJvdG9idWYuT25lb2ZPcHRpb25zIqQCChNFbnVtRGVzY3JpcHRvclByb3Rv", + "EgwKBG5hbWUYASABKAkSOAoFdmFsdWUYAiADKAsyKS5nb29nbGUucHJvdG9i", + "dWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvEi0KB29wdGlvbnMYAyABKAsy", + "HC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMSTgoOcmVzZXJ2ZWRfcmFu", + "Z2UYBCADKAsyNi5nb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90", + "by5FbnVtUmVzZXJ2ZWRSYW5nZRIVCg1yZXNlcnZlZF9uYW1lGAUgAygJGi8K", + "EUVudW1SZXNlcnZlZFJhbmdlEg0KBXN0YXJ0GAEgASgFEgsKA2VuZBgCIAEo", + "BSJsChhFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRIO", + "CgZudW1iZXIYAiABKAUSMgoHb3B0aW9ucxgDIAEoCzIhLmdvb2dsZS5wcm90", + "b2J1Zi5FbnVtVmFsdWVPcHRpb25zIpABChZTZXJ2aWNlRGVzY3JpcHRvclBy", + "b3RvEgwKBG5hbWUYASABKAkSNgoGbWV0aG9kGAIgAygLMiYuZ29vZ2xlLnBy", + "b3RvYnVmLk1ldGhvZERlc2NyaXB0b3JQcm90bxIwCgdvcHRpb25zGAMgASgL", + "Mh8uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zIsEBChVNZXRob2RE", + "ZXNjcmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRISCgppbnB1dF90eXBlGAIg", + "ASgJEhMKC291dHB1dF90eXBlGAMgASgJEi8KB29wdGlvbnMYBCABKAsyHi5n", + "b29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucxIfChBjbGllbnRfc3RyZWFt", + "aW5nGAUgASgIOgVmYWxzZRIfChBzZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVm", + "YWxzZSLUBgoLRmlsZU9wdGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwK", + "FGphdmFfb3V0ZXJfY2xhc3NuYW1lGAggASgJEiIKE2phdmFfbXVsdGlwbGVf", + "ZmlsZXMYCiABKAg6BWZhbHNlEikKHWphdmFfZ2VuZXJhdGVfZXF1YWxzX2Fu", + "ZF9oYXNoGBQgASgIQgIYARIlChZqYXZhX3N0cmluZ19jaGVja191dGY4GBsg", + "ASgIOgVmYWxzZRJGCgxvcHRpbWl6ZV9mb3IYCSABKA4yKS5nb29nbGUucHJv", + "dG9idWYuRmlsZU9wdGlvbnMuT3B0aW1pemVNb2RlOgVTUEVFRBISCgpnb19w", + "YWNrYWdlGAsgASgJEiIKE2NjX2dlbmVyaWNfc2VydmljZXMYECABKAg6BWZh", + "bHNlEiQKFWphdmFfZ2VuZXJpY19zZXJ2aWNlcxgRIAEoCDoFZmFsc2USIgoT", + "cHlfZ2VuZXJpY19zZXJ2aWNlcxgSIAEoCDoFZmFsc2USIwoUcGhwX2dlbmVy", + "aWNfc2VydmljZXMYKiABKAg6BWZhbHNlEhkKCmRlcHJlY2F0ZWQYFyABKAg6", + "BWZhbHNlEh4KEGNjX2VuYWJsZV9hcmVuYXMYHyABKAg6BHRydWUSGQoRb2Jq", + "Y19jbGFzc19wcmVmaXgYJCABKAkSGAoQY3NoYXJwX25hbWVzcGFjZRglIAEo", + "CRIUCgxzd2lmdF9wcmVmaXgYJyABKAkSGAoQcGhwX2NsYXNzX3ByZWZpeBgo", + "IAEoCRIVCg1waHBfbmFtZXNwYWNlGCkgASgJEh4KFnBocF9tZXRhZGF0YV9u", + "YW1lc3BhY2UYLCABKAkSFAoMcnVieV9wYWNrYWdlGC0gASgJEi0KCGZlYXR1", + "cmVzGDIgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQSQwoUdW5p", + "bnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVu", + "aW50ZXJwcmV0ZWRPcHRpb24iOgoMT3B0aW1pemVNb2RlEgkKBVNQRUVEEAES", + "DQoJQ09ERV9TSVpFEAISEAoMTElURV9SVU5USU1FEAMqCQjoBxCAgICAAkoE", + "CCYQJyLnAgoOTWVzc2FnZU9wdGlvbnMSJgoXbWVzc2FnZV9zZXRfd2lyZV9m", + "b3JtYXQYASABKAg6BWZhbHNlEi4KH25vX3N0YW5kYXJkX2Rlc2NyaXB0b3Jf", + "YWNjZXNzb3IYAiABKAg6BWZhbHNlEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZh", + "bHNlEhEKCW1hcF9lbnRyeRgHIAEoCBIyCiZkZXByZWNhdGVkX2xlZ2FjeV9q", + "c29uX2ZpZWxkX2NvbmZsaWN0cxgLIAEoCEICGAESLQoIZmVhdHVyZXMYDCAB", + "KAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldBJDChR1bmludGVycHJl", + "dGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnBy", + "ZXRlZE9wdGlvbioJCOgHEICAgIACSgQIBBAFSgQIBRAGSgQIBhAHSgQICBAJ", + "SgQICRAKIo0JCgxGaWVsZE9wdGlvbnMSOgoFY3R5cGUYASABKA4yIy5nb29n", + "bGUucHJvdG9idWYuRmllbGRPcHRpb25zLkNUeXBlOgZTVFJJTkcSDgoGcGFj", + "a2VkGAIgASgIEj8KBmpzdHlwZRgGIAEoDjIkLmdvb2dsZS5wcm90b2J1Zi5G", + "aWVsZE9wdGlvbnMuSlNUeXBlOglKU19OT1JNQUwSEwoEbGF6eRgFIAEoCDoF", + "ZmFsc2USHgoPdW52ZXJpZmllZF9sYXp5GA8gASgIOgVmYWxzZRIZCgpkZXBy", + "ZWNhdGVkGAMgASgIOgVmYWxzZRITCgR3ZWFrGAogASgIOgVmYWxzZRIbCgxk", + "ZWJ1Z19yZWRhY3QYECABKAg6BWZhbHNlEkAKCXJldGVudGlvbhgRIAEoDjIt", + "Lmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuT3B0aW9uUmV0ZW50aW9u", + "Ej8KB3RhcmdldHMYEyADKA4yLi5nb29nbGUucHJvdG9idWYuRmllbGRPcHRp", + "b25zLk9wdGlvblRhcmdldFR5cGUSRgoQZWRpdGlvbl9kZWZhdWx0cxgUIAMo", + "CzIsLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuRWRpdGlvbkRlZmF1", + "bHQSLQoIZmVhdHVyZXMYFSABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVy", + "ZVNldBJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUu", + "cHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbhpKCg5FZGl0aW9uRGVmYXVs", + "dBIpCgdlZGl0aW9uGAMgASgOMhguZ29vZ2xlLnByb3RvYnVmLkVkaXRpb24S", + "DQoFdmFsdWUYAiABKAkiLwoFQ1R5cGUSCgoGU1RSSU5HEAASCAoEQ09SRBAB", + "EhAKDFNUUklOR19QSUVDRRACIjUKBkpTVHlwZRINCglKU19OT1JNQUwQABIN", + "CglKU19TVFJJTkcQARINCglKU19OVU1CRVIQAiJVCg9PcHRpb25SZXRlbnRp", + "b24SFQoRUkVURU5USU9OX1VOS05PV04QABIVChFSRVRFTlRJT05fUlVOVElN", + "RRABEhQKEFJFVEVOVElPTl9TT1VSQ0UQAiKMAgoQT3B0aW9uVGFyZ2V0VHlw", + "ZRIXChNUQVJHRVRfVFlQRV9VTktOT1dOEAASFAoQVEFSR0VUX1RZUEVfRklM", + "RRABEh8KG1RBUkdFVF9UWVBFX0VYVEVOU0lPTl9SQU5HRRACEhcKE1RBUkdF", + "VF9UWVBFX01FU1NBR0UQAxIVChFUQVJHRVRfVFlQRV9GSUVMRBAEEhUKEVRB", + "UkdFVF9UWVBFX09ORU9GEAUSFAoQVEFSR0VUX1RZUEVfRU5VTRAGEhoKFlRB", + "UkdFVF9UWVBFX0VOVU1fRU5UUlkQBxIXChNUQVJHRVRfVFlQRV9TRVJWSUNF", + "EAgSFgoSVEFSR0VUX1RZUEVfTUVUSE9EEAkqCQjoBxCAgICAAkoECAQQBUoE", + "CBIQEyKNAQoMT25lb2ZPcHRpb25zEi0KCGZlYXR1cmVzGAEgASgLMhsuZ29v", + "Z2xlLnByb3RvYnVmLkZlYXR1cmVTZXQSQwoUdW5pbnRlcnByZXRlZF9vcHRp", + "b24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRp", + "b24qCQjoBxCAgICAAiL2AQoLRW51bU9wdGlvbnMSEwoLYWxsb3dfYWxpYXMY", + "AiABKAgSGQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USMgomZGVwcmVjYXRl", + "ZF9sZWdhY3lfanNvbl9maWVsZF9jb25mbGljdHMYBiABKAhCAhgBEi0KCGZl", + "YXR1cmVzGAcgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQSQwoU", + "dW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVm", + "LlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAkoECAUQBiLJAQoQRW51", + "bVZhbHVlT3B0aW9ucxIZCgpkZXByZWNhdGVkGAEgASgIOgVmYWxzZRItCghm", + "ZWF0dXJlcxgCIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0EhsK", + "DGRlYnVnX3JlZGFjdBgDIAEoCDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9v", "cHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRP", - "cHRpb24qCQjoBxCAgICAAkoECAQQBUoECAUQBkoECAYQB0oECAgQCUoECAkQ", - "CiKNCQoMRmllbGRPcHRpb25zEjoKBWN0eXBlGAEgASgOMiMuZ29vZ2xlLnBy", - "b3RvYnVmLkZpZWxkT3B0aW9ucy5DVHlwZToGU1RSSU5HEg4KBnBhY2tlZBgC", - "IAEoCBI/CgZqc3R5cGUYBiABKA4yJC5nb29nbGUucHJvdG9idWYuRmllbGRP", - "cHRpb25zLkpTVHlwZToJSlNfTk9STUFMEhMKBGxhenkYBSABKAg6BWZhbHNl", - "Eh4KD3VudmVyaWZpZWRfbGF6eRgPIAEoCDoFZmFsc2USGQoKZGVwcmVjYXRl", - "ZBgDIAEoCDoFZmFsc2USEwoEd2VhaxgKIAEoCDoFZmFsc2USGwoMZGVidWdf", - "cmVkYWN0GBAgASgIOgVmYWxzZRJACglyZXRlbnRpb24YESABKA4yLS5nb29n", - "bGUucHJvdG9idWYuRmllbGRPcHRpb25zLk9wdGlvblJldGVudGlvbhI/Cgd0", - "YXJnZXRzGBMgAygOMi4uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5P", - "cHRpb25UYXJnZXRUeXBlEkYKEGVkaXRpb25fZGVmYXVsdHMYFCADKAsyLC5n", - "b29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkVkaXRpb25EZWZhdWx0Ei0K", - "CGZlYXR1cmVzGBUgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQS", - "QwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3Rv", - "YnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24aSgoORWRpdGlvbkRlZmF1bHQSKQoH", - "ZWRpdGlvbhgDIAEoDjIYLmdvb2dsZS5wcm90b2J1Zi5FZGl0aW9uEg0KBXZh", - "bHVlGAIgASgJIi8KBUNUeXBlEgoKBlNUUklORxAAEggKBENPUkQQARIQCgxT", - "VFJJTkdfUElFQ0UQAiI1CgZKU1R5cGUSDQoJSlNfTk9STUFMEAASDQoJSlNf", - "U1RSSU5HEAESDQoJSlNfTlVNQkVSEAIiVQoPT3B0aW9uUmV0ZW50aW9uEhUK", - "EVJFVEVOVElPTl9VTktOT1dOEAASFQoRUkVURU5USU9OX1JVTlRJTUUQARIU", - "ChBSRVRFTlRJT05fU09VUkNFEAIijAIKEE9wdGlvblRhcmdldFR5cGUSFwoT", - "VEFSR0VUX1RZUEVfVU5LTk9XThAAEhQKEFRBUkdFVF9UWVBFX0ZJTEUQARIf", - "ChtUQVJHRVRfVFlQRV9FWFRFTlNJT05fUkFOR0UQAhIXChNUQVJHRVRfVFlQ", - "RV9NRVNTQUdFEAMSFQoRVEFSR0VUX1RZUEVfRklFTEQQBBIVChFUQVJHRVRf", - "VFlQRV9PTkVPRhAFEhQKEFRBUkdFVF9UWVBFX0VOVU0QBhIaChZUQVJHRVRf", - "VFlQRV9FTlVNX0VOVFJZEAcSFwoTVEFSR0VUX1RZUEVfU0VSVklDRRAIEhYK", - "ElRBUkdFVF9UWVBFX01FVEhPRBAJKgkI6AcQgICAgAJKBAgEEAVKBAgSEBMi", - "jQEKDE9uZW9mT3B0aW9ucxItCghmZWF0dXJlcxgBIAEoCzIbLmdvb2dsZS5w", + "cHRpb24qCQjoBxCAgICAAiKqAQoOU2VydmljZU9wdGlvbnMSLQoIZmVhdHVy", + "ZXMYIiABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldBIZCgpkZXBy", + "ZWNhdGVkGCEgASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29wdGlvbhjn", + "ByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJ", + "COgHEICAgIACItwCCg1NZXRob2RPcHRpb25zEhkKCmRlcHJlY2F0ZWQYISAB", + "KAg6BWZhbHNlEl8KEWlkZW1wb3RlbmN5X2xldmVsGCIgASgOMi8uZ29vZ2xl", + "LnByb3RvYnVmLk1ldGhvZE9wdGlvbnMuSWRlbXBvdGVuY3lMZXZlbDoTSURF", + "TVBPVEVOQ1lfVU5LTk9XThItCghmZWF0dXJlcxgjIAEoCzIbLmdvb2dsZS5w", "cm90b2J1Zi5GZWF0dXJlU2V0EkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcH", - "IAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI", - "6AcQgICAgAIi9gEKC0VudW1PcHRpb25zEhMKC2FsbG93X2FsaWFzGAIgASgI", - "EhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEjIKJmRlcHJlY2F0ZWRfbGVn", - "YWN5X2pzb25fZmllbGRfY29uZmxpY3RzGAYgASgIQgIYARItCghmZWF0dXJl", - "cxgHIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0EkMKFHVuaW50", - "ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5Vbmlu", - "dGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgFEAYiyQEKEEVudW1WYWx1", - "ZU9wdGlvbnMSGQoKZGVwcmVjYXRlZBgBIAEoCDoFZmFsc2USLQoIZmVhdHVy", - "ZXMYAiABKAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldBIbCgxkZWJ1", - "Z19yZWRhY3QYAyABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9u", - "GOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9u", - "KgkI6AcQgICAgAIiqgEKDlNlcnZpY2VPcHRpb25zEi0KCGZlYXR1cmVzGCIg", - "ASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQSGQoKZGVwcmVjYXRl", - "ZBghIAEoCDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygL", - "MiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCA", - "gICAAiLcAgoNTWV0aG9kT3B0aW9ucxIZCgpkZXByZWNhdGVkGCEgASgIOgVm", - "YWxzZRJfChFpZGVtcG90ZW5jeV9sZXZlbBgiIAEoDjIvLmdvb2dsZS5wcm90", - "b2J1Zi5NZXRob2RPcHRpb25zLklkZW1wb3RlbmN5TGV2ZWw6E0lERU1QT1RF", - "TkNZX1VOS05PV04SLQoIZmVhdHVyZXMYIyABKAsyGy5nb29nbGUucHJvdG9i", - "dWYuRmVhdHVyZVNldBJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsy", - "JC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiJQChBJZGVt", - "cG90ZW5jeUxldmVsEhcKE0lERU1QT1RFTkNZX1VOS05PV04QABITCg9OT19T", - "SURFX0VGRkVDVFMQARIOCgpJREVNUE9URU5UEAIqCQjoBxCAgICAAiKeAgoT", - "VW5pbnRlcnByZXRlZE9wdGlvbhI7CgRuYW1lGAIgAygLMi0uZ29vZ2xlLnBy", - "b3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQSGAoQaWRlbnRp", - "Zmllcl92YWx1ZRgDIAEoCRIaChJwb3NpdGl2ZV9pbnRfdmFsdWUYBCABKAQS", - "GgoSbmVnYXRpdmVfaW50X3ZhbHVlGAUgASgDEhQKDGRvdWJsZV92YWx1ZRgG", - "IAEoARIUCgxzdHJpbmdfdmFsdWUYByABKAwSFwoPYWdncmVnYXRlX3ZhbHVl", - "GAggASgJGjMKCE5hbWVQYXJ0EhEKCW5hbWVfcGFydBgBIAIoCRIUCgxpc19l", - "eHRlbnNpb24YAiACKAginQkKCkZlYXR1cmVTZXQSfAoOZmllbGRfcHJlc2Vu", - "Y2UYASABKA4yKS5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5GaWVsZFBy", - "ZXNlbmNlQjmIAQGYAQSYAQGiAQ0SCEVYUExJQ0lUGOYHogENEghJTVBMSUNJ", - "VBjnB6IBDRIIRVhQTElDSVQY6AcSXAoJZW51bV90eXBlGAIgASgOMiQuZ29v", - "Z2xlLnByb3RvYnVmLkZlYXR1cmVTZXQuRW51bVR5cGVCI4gBAZgBBpgBAaIB", - "CxIGQ0xPU0VEGOYHogEJEgRPUEVOGOcHEnsKF3JlcGVhdGVkX2ZpZWxkX2Vu", - "Y29kaW5nGAMgASgOMjEuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQuUmVw", - "ZWF0ZWRGaWVsZEVuY29kaW5nQieIAQGYAQSYAQGiAQ0SCEVYUEFOREVEGOYH", - "ogELEgZQQUNLRUQY5wcSaAoPdXRmOF92YWxpZGF0aW9uGAQgASgOMiouZ29v", - "Z2xlLnByb3RvYnVmLkZlYXR1cmVTZXQuVXRmOFZhbGlkYXRpb25CI4gBAZgB", - "BJgBAaIBCRIETk9ORRjmB6IBCxIGVkVSSUZZGOcHEmcKEG1lc3NhZ2VfZW5j", - "b2RpbmcYBSABKA4yKy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5NZXNz", - "YWdlRW5jb2RpbmdCIIgBAZgBBJgBAaIBFBIPTEVOR1RIX1BSRUZJWEVEGOYH", - "EnAKC2pzb25fZm9ybWF0GAYgASgOMiYuZ29vZ2xlLnByb3RvYnVmLkZlYXR1", - "cmVTZXQuSnNvbkZvcm1hdEIziAEBmAEDmAEGmAEBogEXEhJMRUdBQ1lfQkVT", - "VF9FRkZPUlQY5geiAQoSBUFMTE9XGOcHIlwKDUZpZWxkUHJlc2VuY2USGgoW", - "RklFTERfUFJFU0VOQ0VfVU5LTk9XThAAEgwKCEVYUExJQ0lUEAESDAoISU1Q", - "TElDSVQQAhITCg9MRUdBQ1lfUkVRVUlSRUQQAyI3CghFbnVtVHlwZRIVChFF", - "TlVNX1RZUEVfVU5LTk9XThAAEggKBE9QRU4QARIKCgZDTE9TRUQQAiJWChVS", - "ZXBlYXRlZEZpZWxkRW5jb2RpbmcSIwofUkVQRUFURURfRklFTERfRU5DT0RJ", - "TkdfVU5LTk9XThAAEgoKBlBBQ0tFRBABEgwKCEVYUEFOREVEEAIiQwoOVXRm", - "OFZhbGlkYXRpb24SGwoXVVRGOF9WQUxJREFUSU9OX1VOS05PV04QABIICgRO", - "T05FEAESCgoGVkVSSUZZEAIiUwoPTWVzc2FnZUVuY29kaW5nEhwKGE1FU1NB", - "R0VfRU5DT0RJTkdfVU5LTk9XThAAEhMKD0xFTkdUSF9QUkVGSVhFRBABEg0K", - "CURFTElNSVRFRBACIkgKCkpzb25Gb3JtYXQSFwoTSlNPTl9GT1JNQVRfVU5L", - "Tk9XThAAEgkKBUFMTE9XEAESFgoSTEVHQUNZX0JFU1RfRUZGT1JUEAIqBgjo", - "BxDpByoGCOkHEOoHKgYIi04QkE5KBgjnBxDoByLAAgoSRmVhdHVyZVNldERl", - "ZmF1bHRzEk4KCGRlZmF1bHRzGAEgAygLMjwuZ29vZ2xlLnByb3RvYnVmLkZl", - "YXR1cmVTZXREZWZhdWx0cy5GZWF0dXJlU2V0RWRpdGlvbkRlZmF1bHQSMQoP", - "bWluaW11bV9lZGl0aW9uGAQgASgOMhguZ29vZ2xlLnByb3RvYnVmLkVkaXRp", - "b24SMQoPbWF4aW11bV9lZGl0aW9uGAUgASgOMhguZ29vZ2xlLnByb3RvYnVm", - "LkVkaXRpb24adAoYRmVhdHVyZVNldEVkaXRpb25EZWZhdWx0EikKB2VkaXRp", - "b24YAyABKA4yGC5nb29nbGUucHJvdG9idWYuRWRpdGlvbhItCghmZWF0dXJl", - "cxgCIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0ItUBCg5Tb3Vy", - "Y2VDb2RlSW5mbxI6Cghsb2NhdGlvbhgBIAMoCzIoLmdvb2dsZS5wcm90b2J1", - "Zi5Tb3VyY2VDb2RlSW5mby5Mb2NhdGlvbhqGAQoITG9jYXRpb24SEAoEcGF0", - "aBgBIAMoBUICEAESEAoEc3BhbhgCIAMoBUICEAESGAoQbGVhZGluZ19jb21t", - "ZW50cxgDIAEoCRIZChF0cmFpbGluZ19jb21tZW50cxgEIAEoCRIhChlsZWFk", - "aW5nX2RldGFjaGVkX2NvbW1lbnRzGAYgAygJIpwCChFHZW5lcmF0ZWRDb2Rl", - "SW5mbxJBCgphbm5vdGF0aW9uGAEgAygLMi0uZ29vZ2xlLnByb3RvYnVmLkdl", - "bmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24awwEKCkFubm90YXRpb24SEAoE", - "cGF0aBgBIAMoBUICEAESEwoLc291cmNlX2ZpbGUYAiABKAkSDQoFYmVnaW4Y", - "AyABKAUSCwoDZW5kGAQgASgFEkgKCHNlbWFudGljGAUgASgOMjYuZ29vZ2xl", - "LnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24uU2VtYW50", - "aWMiKAoIU2VtYW50aWMSCAoETk9ORRAAEgcKA1NFVBABEgkKBUFMSUFTEAIq", - "6gEKB0VkaXRpb24SEwoPRURJVElPTl9VTktOT1dOEAASEwoORURJVElPTl9Q", - "Uk9UTzIQ5gcSEwoORURJVElPTl9QUk9UTzMQ5wcSEQoMRURJVElPTl8yMDIz", - "EOgHEhcKE0VESVRJT05fMV9URVNUX09OTFkQARIXChNFRElUSU9OXzJfVEVT", - "VF9PTkxZEAISHQoXRURJVElPTl85OTk5N19URVNUX09OTFkQnY0GEh0KF0VE", - "SVRJT05fOTk5OThfVEVTVF9PTkxZEJ6NBhIdChdFRElUSU9OXzk5OTk5X1RF", - "U1RfT05MWRCfjQZCfgoTY29tLmdvb2dsZS5wcm90b2J1ZkIQRGVzY3JpcHRv", - "clByb3Rvc0gBWi1nb29nbGUuZ29sYW5nLm9yZy9wcm90b2J1Zi90eXBlcy9k", - "ZXNjcmlwdG9ycGL4AQGiAgNHUEKqAhpHb29nbGUuUHJvdG9idWYuUmVmbGVj", - "dGlvbg==")); + "IAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIlAK", + "EElkZW1wb3RlbmN5TGV2ZWwSFwoTSURFTVBPVEVOQ1lfVU5LTk9XThAAEhMK", + "D05PX1NJREVfRUZGRUNUUxABEg4KCklERU1QT1RFTlQQAioJCOgHEICAgIAC", + "Ip4CChNVbmludGVycHJldGVkT3B0aW9uEjsKBG5hbWUYAiADKAsyLS5nb29n", + "bGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydBIYChBp", + "ZGVudGlmaWVyX3ZhbHVlGAMgASgJEhoKEnBvc2l0aXZlX2ludF92YWx1ZRgE", + "IAEoBBIaChJuZWdhdGl2ZV9pbnRfdmFsdWUYBSABKAMSFAoMZG91YmxlX3Zh", + "bHVlGAYgASgBEhQKDHN0cmluZ192YWx1ZRgHIAEoDBIXCg9hZ2dyZWdhdGVf", + "dmFsdWUYCCABKAkaMwoITmFtZVBhcnQSEQoJbmFtZV9wYXJ0GAEgAigJEhQK", + "DGlzX2V4dGVuc2lvbhgCIAIoCCKdCQoKRmVhdHVyZVNldBJ8Cg5maWVsZF9w", + "cmVzZW5jZRgBIAEoDjIpLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0LkZp", + "ZWxkUHJlc2VuY2VCOYgBAZgBBJgBAaIBDRIIRVhQTElDSVQY5geiAQ0SCElN", + "UExJQ0lUGOcHogENEghFWFBMSUNJVBjoBxJcCgllbnVtX3R5cGUYAiABKA4y", + "JC5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5FbnVtVHlwZUIjiAEBmAEG", + "mAEBogELEgZDTE9TRUQY5geiAQkSBE9QRU4Y5wcSewoXcmVwZWF0ZWRfZmll", + "bGRfZW5jb2RpbmcYAyABKA4yMS5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNl", + "dC5SZXBlYXRlZEZpZWxkRW5jb2RpbmdCJ4gBAZgBBJgBAaIBDRIIRVhQQU5E", + "RUQY5geiAQsSBlBBQ0tFRBjnBxJoCg91dGY4X3ZhbGlkYXRpb24YBCABKA4y", + "Ki5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5VdGY4VmFsaWRhdGlvbkIj", + "iAEBmAEEmAEBogEJEgROT05FGOYHogELEgZWRVJJRlkY5wcSZwoQbWVzc2Fn", + "ZV9lbmNvZGluZxgFIAEoDjIrLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0", + "Lk1lc3NhZ2VFbmNvZGluZ0IgiAEBmAEEmAEBogEUEg9MRU5HVEhfUFJFRklY", + "RUQY5gcScAoLanNvbl9mb3JtYXQYBiABKA4yJi5nb29nbGUucHJvdG9idWYu", + "RmVhdHVyZVNldC5Kc29uRm9ybWF0QjOIAQGYAQOYAQaYAQGiARcSEkxFR0FD", + "WV9CRVNUX0VGRk9SVBjmB6IBChIFQUxMT1cY5wciXAoNRmllbGRQcmVzZW5j", + "ZRIaChZGSUVMRF9QUkVTRU5DRV9VTktOT1dOEAASDAoIRVhQTElDSVQQARIM", + "CghJTVBMSUNJVBACEhMKD0xFR0FDWV9SRVFVSVJFRBADIjcKCEVudW1UeXBl", + "EhUKEUVOVU1fVFlQRV9VTktOT1dOEAASCAoET1BFThABEgoKBkNMT1NFRBAC", + "IlYKFVJlcGVhdGVkRmllbGRFbmNvZGluZxIjCh9SRVBFQVRFRF9GSUVMRF9F", + "TkNPRElOR19VTktOT1dOEAASCgoGUEFDS0VEEAESDAoIRVhQQU5ERUQQAiJD", + "Cg5VdGY4VmFsaWRhdGlvbhIbChdVVEY4X1ZBTElEQVRJT05fVU5LTk9XThAA", + "EgoKBlZFUklGWRACEggKBE5PTkUQAyJTCg9NZXNzYWdlRW5jb2RpbmcSHAoY", + "TUVTU0FHRV9FTkNPRElOR19VTktOT1dOEAASEwoPTEVOR1RIX1BSRUZJWEVE", + "EAESDQoJREVMSU1JVEVEEAIiSAoKSnNvbkZvcm1hdBIXChNKU09OX0ZPUk1B", + "VF9VTktOT1dOEAASCQoFQUxMT1cQARIWChJMRUdBQ1lfQkVTVF9FRkZPUlQQ", + "AioGCOgHEOkHKgYI6QcQ6gcqBgiLThCQTkoGCOcHEOgHIsACChJGZWF0dXJl", + "U2V0RGVmYXVsdHMSTgoIZGVmYXVsdHMYASADKAsyPC5nb29nbGUucHJvdG9i", + "dWYuRmVhdHVyZVNldERlZmF1bHRzLkZlYXR1cmVTZXRFZGl0aW9uRGVmYXVs", + "dBIxCg9taW5pbXVtX2VkaXRpb24YBCABKA4yGC5nb29nbGUucHJvdG9idWYu", + "RWRpdGlvbhIxCg9tYXhpbXVtX2VkaXRpb24YBSABKA4yGC5nb29nbGUucHJv", + "dG9idWYuRWRpdGlvbhp0ChhGZWF0dXJlU2V0RWRpdGlvbkRlZmF1bHQSKQoH", + "ZWRpdGlvbhgDIAEoDjIYLmdvb2dsZS5wcm90b2J1Zi5FZGl0aW9uEi0KCGZl", + "YXR1cmVzGAIgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQi1QEK", + "DlNvdXJjZUNvZGVJbmZvEjoKCGxvY2F0aW9uGAEgAygLMiguZ29vZ2xlLnBy", + "b3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uGoYBCghMb2NhdGlvbhIQ", + "CgRwYXRoGAEgAygFQgIQARIQCgRzcGFuGAIgAygFQgIQARIYChBsZWFkaW5n", + "X2NvbW1lbnRzGAMgASgJEhkKEXRyYWlsaW5nX2NvbW1lbnRzGAQgASgJEiEK", + "GWxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMYBiADKAkinAIKEUdlbmVyYXRl", + "ZENvZGVJbmZvEkEKCmFubm90YXRpb24YASADKAsyLS5nb29nbGUucHJvdG9i", + "dWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbhrDAQoKQW5ub3RhdGlv", + "bhIQCgRwYXRoGAEgAygFQgIQARITCgtzb3VyY2VfZmlsZRgCIAEoCRINCgVi", + "ZWdpbhgDIAEoBRILCgNlbmQYBCABKAUSSAoIc2VtYW50aWMYBSABKA4yNi5n", + "b29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvbi5T", + "ZW1hbnRpYyIoCghTZW1hbnRpYxIICgROT05FEAASBwoDU0VUEAESCQoFQUxJ", + "QVMQAir/AQoHRWRpdGlvbhITCg9FRElUSU9OX1VOS05PV04QABITCg5FRElU", + "SU9OX1BST1RPMhDmBxITCg5FRElUSU9OX1BST1RPMxDnBxIRCgxFRElUSU9O", + "XzIwMjMQ6AcSFwoTRURJVElPTl8xX1RFU1RfT05MWRABEhcKE0VESVRJT05f", + "Ml9URVNUX09OTFkQAhIdChdFRElUSU9OXzk5OTk3X1RFU1RfT05MWRCdjQYS", + "HQoXRURJVElPTl85OTk5OF9URVNUX09OTFkQno0GEh0KF0VESVRJT05fOTk5", + "OTlfVEVTVF9PTkxZEJ+NBhITCgtFRElUSU9OX01BWBD/////B0J+ChNjb20u", + "Z29vZ2xlLnByb3RvYnVmQhBEZXNjcmlwdG9yUHJvdG9zSAFaLWdvb2dsZS5n", + "b2xhbmcub3JnL3Byb3RvYnVmL3R5cGVzL2Rlc2NyaXB0b3JwYvgBAaICA0dQ", + "QqoCGkdvb2dsZS5Qcm90b2J1Zi5SZWZsZWN0aW9u")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.Reflection.Edition), }, null, new pbr::GeneratedClrTypeInfo[] { @@ -301,6 +301,12 @@ namespace Google.Protobuf.Reflection { [pbr::OriginalName("EDITION_99997_TEST_ONLY")] _99997TestOnly = 99997, [pbr::OriginalName("EDITION_99998_TEST_ONLY")] _99998TestOnly = 99998, [pbr::OriginalName("EDITION_99999_TEST_ONLY")] _99999TestOnly = 99999, + /// + /// Placeholder for specifying unbounded edition support. This should only + /// ever be used by plugins that can expect to never require any changes to + /// support a new edition. + /// + [pbr::OriginalName("EDITION_MAX")] Max = 2147483647, } #endregion @@ -3387,12 +3393,12 @@ namespace Google.Protobuf.Reflection { /// If true, this is a proto3 "optional". When a proto3 field is optional, it /// tracks presence regardless of field type. /// - /// When proto3_optional is true, this field must be belong to a oneof to - /// signal to old proto3 clients that presence is tracked for this field. This - /// oneof is known as a "synthetic" oneof, and this field must be its sole - /// member (each proto3 optional field gets its own synthetic oneof). Synthetic - /// oneofs exist in the descriptor only, and do not generate any API. Synthetic - /// oneofs must be ordered after all "real" oneofs. + /// When proto3_optional is true, this field must belong to a oneof to signal + /// to old proto3 clients that presence is tracked for this field. This oneof + /// is known as a "synthetic" oneof, and this field must be its sole member + /// (each proto3 optional field gets its own synthetic oneof). Synthetic oneofs + /// exist in the descriptor only, and do not generate any API. Synthetic oneofs + /// must be ordered after all "real" oneofs. /// /// For message fields, proto3_optional doesn't create any semantic change, /// since non-repeated message fields always track presence. However it still @@ -12256,8 +12262,8 @@ namespace Google.Protobuf.Reflection { public enum Utf8Validation { [pbr::OriginalName("UTF8_VALIDATION_UNKNOWN")] Unknown = 0, - [pbr::OriginalName("NONE")] None = 1, [pbr::OriginalName("VERIFY")] Verify = 2, + [pbr::OriginalName("NONE")] None = 3, } public enum MessageEncoding { diff --git a/docs/design/editions/README.md b/docs/design/editions/README.md index 483ce860c0..c551f91ab0 100644 --- a/docs/design/editions/README.md +++ b/docs/design/editions/README.md @@ -36,3 +36,4 @@ The following topics are in this repository: * [Edition Naming](edition-naming.md) * [Editions Feature Visibility](editions-feature-visibility.md) * [Legacy Syntax Editions](legacy-syntax-editions.md) +* [Editions: Feature Extension Layout](editions-feature-extension-layout.md) \ No newline at end of file diff --git a/docs/design/editions/editions-feature-extension-layout.md b/docs/design/editions/editions-feature-extension-layout.md new file mode 100644 index 0000000000..67626a4388 --- /dev/null +++ b/docs/design/editions/editions-feature-extension-layout.md @@ -0,0 +1,150 @@ +# Editions: Feature Extension Layout + +**Author:** [@mkruskal-google](https://github.com/mkruskal-google), +[@zhangskz](https://github.com/zhangskz) + +**Approved:** 2023-08-23 + +## Background + +"[What are Protobuf Editions](what-are-protobuf-editions.md)" lays out a plan +for allowing for more targeted features not owned by the protobuf team. It uses +extensions of the global features proto to implement this. One thing that was +left a bit ambiguous was *who* should own these extensions. Language, code +generator, and runtime implementations are all similar but not identical +distinctions. + +"Editions Zero Feature: utf8_validation" (not available externally, though a +later version, +"[Editions Zero: utf8_validation Without Problematic Options](editions-zero-utf8_validation.md)" +is) is a recent plan to add a new set of generator features for utf8 validation. +While the sole feature we had originally created (`legacy_closed_enum` in Java +and C++) didn't have any ambiguity here, this one did. Specifically in Python, +the current behaviors across proto2/proto3 are distinct for all 3 +implementations: pure python, Python/C++, Python/upb. + +## Overview + +In meetings, we've discussed various alternatives, captured below. The original +plan was to make feature extensions runtime implementation-specific (e.g. C++, +Java, Python, upb). There are some notable complications that came up though: + +1. **Polyglot** - it's not clear how upb or C++ runtimes should behave in + multi-language situations. Which feature sets do they consider for runtime + behaviors? *Note: this is already a serious issue today, where all proto2 + strings and many proto3 strings are completely unsafe across languages.* + +2. **Shared Implementations** - Runtimes like upb and C++ are used as backing + implementations of multiple other languages (e.g. Python, Rust, Ruby, PHP). + If we have a single set of `upb` or `cpp` features, migrating to those + shared implementations would be more difficult (since there's no independent + switches per-language). *Note: this is already the situation we're in today, + where switching the runtime implementation can cause subtle and dangerous + behavior changes.* + +Given that we only have two behaviors, and one of them is unambiguous, it seems +reasonable to punt on this decision until we have more information. We may +encounter more edge cases that require feature extensions (and give us more +information) during the rollout of edition zero. We also have a lot of freedom +to re-model features in later editions, so keeping the initial implementation as +simple as possible seems best (i.e. Alternative 2). + +## Alternatives + +### Alternative 1: Runtime Implementation Features + +Features would be per-runtime implementation as originally described in +"Editions Zero Feature: utf8_validation." For example, Protobuf Python users +would set different features depending on the backing implementation (e.g. +`features.(pb.cpp).`, `features.(pb.upb).`). + +#### Pros + +* Most consistent with range of behaviors expressible pre-Editions + +#### Cons + +* Implementation may / should not be obvious to users. +* Lack of levers specifically for language / implementation combos. For + example, there is no way to set Python-C++ behavior independently of C++ + behavior which may make migration harder from other Python implementations. + +### Alternative 2: Generator Features + +Features would be per-generator only (i.e. each protoc plugin would own one set +of features). This was the second decision we made in later discussions, and +while very similar to the above alternative, it's more inline with our goal of +making features primarily for codegen. + +For example, all Python implementations would share the same set of features +(e.g. `features.(pb.python).`). However, certain features could be +targeted to specific implementations (e.g. +`features.(pb.python).upb_utf8_validation` would only be used by Python/upb). + +#### Pros + +* Allows independent controls of shared implementations in different target + languages (e.g. Python's upb feature won't affect PHP). + +#### Cons + +* Possible complexity in upb to understand which language's features to + respect. UPB is not currently aware of what language it is being used for. +* Limits in-process sharing across languages with shared implementations (e.g. + Python upb, PHP upb) in the case of conflicting behaviors. + * Additional checks may be needed. + +### Alternative 3: Migrate to bytes + +Since this whole discussion revolves around the utf8 validation feature, one +option would be to just remove it from edition zero. Instead of adding a new +toggle for UTF8 behavior, we could simply migrate everyone who doesn't enforce +utf8 today to `bytes`. This would likely need another new *codegen* feature for +generating byte getters/setters as strings, but that wouldn't have any of the +ambiguity we're seeing today. + +Unfortunately, this doesn't seem feasible because of all the different behaviors +laid out in "Editions Zero Feature: utf8_validation." UTF8 validation isn't +really a binary on/off decision, and it can vary widely between languages. There +are many cases where UTF8 is validated in **some** languages but not others, and +there's also the C++ "hint" behavior that logs errors but allows invalid UTF8. + +**Note:** This could still be partially done in a follow-up LSC by targeting +specific combinations of the new feature that disable validation in all relevant +languages. + +#### Pros + +* Punts on the issue, we wouldn't need any upb features and C++ features would + all be code-gen only +* Simplifies the situation, avoids adding a very complicated feature in + edition zero + +#### Cons + +* Not really possible given the current complexity +* There are O(10M) proto2 string fields that would be blindly changed to bytes + +### Alternative 4: Nested Features + +Another option is to allow for shared feature set messages. For example, upb +would define a feature message, but *not* make it an extension of the global +`FeatureSet`. Instead, languages with upb implementations would have a field of +this type to allow for finer-grained controls. C++ would both extend the global +`FeatureSet` and also be allowed as a field in other languages. + +For example, python utf8 validation could be specified as: + +We could have checks during feature validation that enforce that impossible +combinations aren't specified. For example, with our current implementation +`features.(pb.python).cpp` should always be identical to `features.(pb.cpp)`, +since we don't have any mechanism for distinguishing them. + +#### Pros + +* Much more explicit than options 1 and 2 + +#### Cons + +* Maybe too explicit? Proto owners would be forced to duplicate a lot of + features diff --git a/docs/design/prototiller/prototiller-reqs-for-editions.md b/docs/design/prototiller/prototiller-reqs-for-editions.md new file mode 100644 index 0000000000..48503296a1 --- /dev/null +++ b/docs/design/prototiller/prototiller-reqs-for-editions.md @@ -0,0 +1,138 @@ +# Prototiller Requirements for Editions + +**Author:** [@mcy](https://github.com/mcy) + +**Approved:** 2022-11-29 + +## Background + +Prototiller is Protobuf's new mass refactoring Swiss army knife, similar to +Buildozer. We plan to use Prototiller to enable LSCs within google3 and to allow +users (internal and external) to modify `.proto` files safely. + +Prototiller is being developed as part of the +[Editions](../editions/what-are-protobuf-editions.md) project, and will +prioritize enabling Editions-related refactorings to unblock Editions migrations +in 2023. This document describes the relevant requirements. + +## Overview + +*Protochangifier Semantic Actions* (not available externally) describes the +original design for the Prototiller interface; it would consume a Protobuf +message that described changes to apply to a `.proto` file passed as input. In +this document, we prescribe a variant of this interface that fulfills *only* the +needs of Editions, while remaining extensible for future change actions. + +Broad requirements are as follows: + +* Actions must include the following Editions-oriented upgrade workflows: + * Upgrade a file to a particular edition, regardless of whether it's in + syntax mode or editions mode, updating features in such a way to be a + no-op. **This is the highest-priority workflow.** + * "Clean up" features in a particular file: i.e., run a simple algorithm + to determine the smallest set of features that need to be present at + each level of the file. + * Modify features from a particular syntax element. +* Actions must be both specific to particular syntax elements (for when change + specs are checked in alongside `.proto` files by Schema Consumers), and + generic (so that a single change spec or set of change specs can power a + large-scale change). + +In this document we provide a recommendation for a Protobuf schema based on the +original Protochangifier design, but geared towards these specific needs. + +This is only a recommendation; the Prototiller project owners should modify this +to suit the implementation; only the requirements in this document are binding, +and the schema is merely an illustration of those requirements. + +The suggested schema is as follows. + +``` +syntax = "proto2"; + +package prototiller; + +// This is the proto that Prototiller accepts as input. +message ChangeSpec { + // Actions to execute on the file. + repeated Action actions = 1; + + // Some changes may result in a wireformat break; changing field type is + // usually unsafe. By default, Prototiller does not allow such changes, + // users can set allow_unsafe_wire_format_changes to true to force the change. + optional bool allow_unsafe_wire_format_changes = 2 [default = false]; + optional bool allow_unsafe_text_format_changes = 3 [default = false]; + optional bool allow_unsafe_json_format_changes = 4 [default = false]; +} + +// A single action. See messages below for description of their +// semantics. +message Action { + oneof kind { + UpgradeEdition upgrade_edition = 20; + CleanUpFeatures clean_up_features = 21; + ModifyFeature modify_feature = 22; + } +} + +// Upgrades the edition of a file to a specified edition. +// Treats syntax mode as being a weird, special edition that cannot be +// upgraded to. +// +// This action is always safe. +message UpgradeEdition { + // The edition to upgrade to. + optional string edition = 1; +} + +// Cleans up features in a file, such that there are as few explicitly set +// features as necessary. +// +// This action is always safe. +message CleanUpFeatures {} + +// Modifies a specific feature on all syntax elements that match and which can +// host that particular feature. +// +// Prototiller must be aware of which changes affect wire format, so that it +// can flag them as unsafe. +message ModifyFeature { + // The name of the feature to modify. + repeated proto2.UninterpretedOption.NamePart feature = 1; + + // A pattern for matching paths to syntax elements to modify. + // + // Elements of this field can either be identifiers, or the string "*", which + // matches all identifiers. Thus, ["foo", "Bar"] matches the message foo.Bar, + // ["foo", "Bar", "*"] matches all fields and nested types of foo.Bar + // (recursively), and ["*"] matches all elements of a file. + repeated string path_pattern = 2; + + // The value to set the feature to. If not set, this means that the + // feature should be deleted. + oneof value { + int64 int_value = 20; + double double_value = 21; + // ... and so on. + } +} +``` + +## Alternatives Considered + +This document does not capture a design so much as requirements that a design +must satisfy, so we will be brief on potential alternatives to the requirements, +and why we decided against them. + +* Omit feature cleanup as its own action, and let it happen implicitly as part + of other actions. + * It is desirable to be able to aggressively run this operation + everywhere, potentially even as part of "format on save" in Cider and + other IDEs. +* Make `ModifyFeature` operate on all syntax elements of a file + simultaneously. + * `ModifyFeature` is intended so that SchemaConsumers can affect + fine-grained control of features in `.proto` files they import. Users + will want to be able to wipe out a feature from all fields in a file, or + perhaps just on a handful of fields they care about. Offering simple + pattern-matching supports both. diff --git a/docs/options.md b/docs/options.md index 18b6b410fa..aee889ecdf 100644 --- a/docs/options.md +++ b/docs/options.md @@ -486,3 +486,8 @@ with info about your project (name and website) so we can add an entry for you. * Website: https://square.github.io/wire/ * Extensions: 1185 + +1. Protons + + * Website: https://github.com/ipfs/protons + * Extensions: 1186 diff --git a/docs/third_party.md b/docs/third_party.md index a3763a974e..b339c4f196 100644 --- a/docs/third_party.md +++ b/docs/third_party.md @@ -169,9 +169,7 @@ Inactive: * https://github.com/thesamet/rpcz (C++/Python, based on ZeroMQ) * https://github.com/w359405949/libmaid (C++, Python) -## Other Utilities - -There are miscellaneous other things you may find useful as a Protocol Buffers developer. +## Build * [Bazel Build](https://bazel.build) * [rules_closure](https://github.com/bazelbuild/rules_closure) @@ -179,17 +177,6 @@ There are miscellaneous other things you may find useful as a Protocol Buffers d * [rules_go](https://github.com/bazelbuild/rules_go) `go` * [rules_protobuf](https://github.com/pubref/rules_protobuf) `java` `c++` `c#` `go` `js-closure` `js-node` `python` `ruby` -* [NetBeans IDE plugin](https://code.google.com/p/protobuf-netbeans-plugin/) -* [Wireshark/Ethereal packet sniffer plugin](https://code.google.com/p/protobuf-wireshark/) -* [Alternate encodings (JSON, XML, HTML) for Java protobufs](https://code.google.com/p/protobuf-java-format/) -* [Another JSON encoder/decoder for Java](https://github.com/sijuv/protobuf-codec) -* [Editor for serialized protobufs](https://code.google.com/p/protobufeditor/) -* [IntelliJ IDEA plugin](http://github.com/jvolkman/intellij-protobuf-editor) -* [IntelliJ Protobuf Plugin](https://github.com/devkanro/intellij-protobuf-plugin) -* [TextMate syntax highlighting](http://github.com/michaeledgar/protobuf-tmbundle) -* [Oracle PL SQL plugin](https://code.google.com/p/protocol-buffer-plsql/) -* [Eclipse editor for protobuf (from Google)](https://code.google.com/p/protobuf-dt/) -* [C++ Builder compatible protobuf](https://github.com/saadware/protobuf-cppbuilder) * Maven Protobuf Compiler Plugin * By xolstice.org ([Documentation](https://www.xolstice.org/protobuf-maven-plugin/)) @@ -197,21 +184,43 @@ There are miscellaneous other things you may find useful as a Protocol Buffers d [![Maven Central](https://img.shields.io/maven-central/v/org.xolstice.maven.plugins/protobuf-maven-plugin.svg)](https://repo1.maven.org/maven2/org/xolstice/maven/plugins/protobuf-maven-plugin/) * https://code.google.com/p/maven-protoc-plugin/ * https://github.com/os72/protoc-jar-maven-plugin +* [Protobuf Plugin for Gradle](https://github.com/google/protobuf-gradle-plugin) +* [Sbt plugin for Protocol Buffers](https://github.com/Atry/sbt-cppp) + +## IDE + +* [Visual Studio Code Support for Protocol Buffers](https://marketplace.visualstudio.com/items?itemName=zxh404.vscode-proto3) +* [Visual Studio Language Service support for Protocol Buffers](http://visualstudiogallery.msdn.microsoft.com/4bc0f38c-b058-4e05-ae38-155e053c19c5) +* [IntelliJ IDEA plugin](http://github.com/jvolkman/intellij-protobuf-editor) +* [IntelliJ Protobuf Plugin](https://github.com/devkanro/intellij-protobuf-plugin) +* [TextMate syntax highlighting](http://github.com/michaeledgar/protobuf-tmbundle) +* [Notepad++ Syntax Highlighting for .proto files](https://github.com/chai2010/notepadplus-protobuf) +* [Eclipse editor for protobuf (from Google)](https://code.google.com/p/protobuf-dt/) +* [NetBeans IDE plugin](https://code.google.com/p/protobuf-netbeans-plugin/) +* [Editor for serialized protobufs](https://code.google.com/p/protobufeditor/) + +## Documentation + * [Documentation generator plugin (Markdown/HTML/DocBook/...)](https://github.com/pseudomuto/protoc-gen-doc) * [DocBook generator for .proto files](https://code.google.com/p/protoc-gen-docbook/) + +## Other Utilities + +There are miscellaneous other things you may find useful as a Protocol Buffers developer. + +* [Wireshark/Ethereal packet sniffer plugin](https://code.google.com/p/protobuf-wireshark/) +* [Alternate encodings (JSON, XML, HTML) for Java protobufs](https://code.google.com/p/protobuf-java-format/) +* [Another JSON encoder/decoder for Java](https://github.com/sijuv/protobuf-codec) +* [Oracle PL SQL plugin](https://code.google.com/p/protocol-buffer-plsql/) +* [C++ Builder compatible protobuf](https://github.com/saadware/protobuf-cppbuilder) * [Protobuf for nginx module](https://github.com/dbcode/protobuf-nginx/) * [RSpec matchers and Cucumber step defs for testing Protocol Buffers](https://github.com/connamara/protobuf_spec) -* [Sbt plugin for Protocol Buffers](https://github.com/Atry/sbt-cppp) -* [Protobuf Plugin for Gradle](https://github.com/google/protobuf-gradle-plugin) * [Multi-platform executable JAR and Java API for protoc](https://github.com/os72/protoc-jar) * [Python scripts to convert between Protocol Buffers and JSON](https://github.com/NextTuesday/py-pb-converters) -* [Visual Studio Language Service support for Protocol Buffers](http://visualstudiogallery.msdn.microsoft.com/4bc0f38c-b058-4e05-ae38-155e053c19c5) -* [Visual Studio Code Support for Protocol Buffers](https://marketplace.visualstudio.com/items?itemName=zxh404.vscode-proto3) * [C++ library for serialization/de-serialization between Protocol Buffers and JSON.](https://github.com/yinqiwen/pbjson) * [ProtoBuf with Java EE7 Expression Language 3.0; pure Java ProtoBuf Parser and Builder.](https://github.com/protobufel/protobuf-el) -* [Notepad++ Syntax Highlighting for .proto files](https://github.com/chai2010/notepadplus-protobuf) * [Linter for .proto files](https://github.com/ckaznocha/protoc-gen-lint) * [Protocol Buffers Dynamic Schema - create protobuf schemas programmatically (Java)](https://github.com/os72/protobuf-dynamic) diff --git a/java/README.md b/java/README.md index fb80b05f27..f6dab2654d 100644 --- a/java/README.md +++ b/java/README.md @@ -23,7 +23,7 @@ If you are using Maven, use the following: com.google.protobuf protobuf-java - 3.24.0 + 3.25.0 ``` @@ -37,14 +37,14 @@ protobuf-java-util package: com.google.protobuf protobuf-java-util - 3.24.0 + 3.25.0 ``` ### Gradle If you are using Gradle, add the following to your `build.gradle` file's -dependencies: `implementation 'com.google.protobuf:protobuf-java:3.24.0'` Again, +dependencies: `implementation 'com.google.protobuf:protobuf-java:3.25.0'` Again, be sure to check that the version number matches (or is newer than) the version number of protoc that you are using. diff --git a/java/bom/pom.xml b/java/bom/pom.xml index 372dcdfda0..411c501fa7 100644 --- a/java/bom/pom.xml +++ b/java/bom/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-bom - 3.24.0 + 3.25.0 pom Protocol Buffers [BOM] diff --git a/java/core/BUILD.bazel b/java/core/BUILD.bazel index 70fe8faa25..4168a54b20 100644 --- a/java/core/BUILD.bazel +++ b/java/core/BUILD.bazel @@ -2,10 +2,10 @@ load("@bazel_skylib//rules:build_test.bzl", "build_test") load("@rules_java//java:defs.bzl", "java_lite_proto_library", "java_proto_library") load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain", "proto_library") -load("//build_defs:java_opts.bzl", "protobuf_java_export", "protobuf_java_library", "protobuf_versioned_java_library") -load("//conformance:defs.bzl", "conformance_test") load("//:protobuf.bzl", "internal_gen_well_known_protos_java") load("//:protobuf_version.bzl", "PROTOBUF_JAVA_VERSION") +load("//build_defs:java_opts.bzl", "protobuf_java_export", "protobuf_java_library", "protobuf_versioned_java_library") +load("//conformance:defs.bzl", "conformance_test") load("//java/internal:testing.bzl", "junit_tests") LITE_SRCS = [ @@ -85,6 +85,7 @@ LITE_SRCS = [ "src/main/java/com/google/protobuf/RawMessageInfo.java", "src/main/java/com/google/protobuf/Reader.java", "src/main/java/com/google/protobuf/RopeByteString.java", + "src/main/java/com/google/protobuf/RuntimeVersion.java", "src/main/java/com/google/protobuf/Schema.java", "src/main/java/com/google/protobuf/SchemaFactory.java", "src/main/java/com/google/protobuf/SchemaUtil.java", @@ -136,6 +137,7 @@ protobuf_versioned_java_library( srcs = LITE_SRCS + [ ":gen_well_known_protos_javalite", ], + automatic_module_name = "com.google.protobuf", bundle_description = "Lite version of Protocol Buffers library. This " + "version is optimized for code size, but does not " + "guarantee API/ABI stability.", @@ -217,6 +219,7 @@ protobuf_versioned_java_library( ) + [ ":gen_well_known_protos_java", ], + automatic_module_name = "com.google.protobuf", bundle_description = "Core Protocol Buffers library. Protocol Buffers " + "are a way of encoding structured data in an " + "efficient yet extensible format.", @@ -470,6 +473,7 @@ LITE_TEST_EXCLUSIONS = [ "src/test/java/com/google/protobuf/FieldPresenceTest.java", "src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java", "src/test/java/com/google/protobuf/GeneratedMessageTest.java", + "src/test/java/com/google/protobuf/LazilyParsedMessageSetTest.java", "src/test/java/com/google/protobuf/LazyFieldTest.java", "src/test/java/com/google/protobuf/LazyStringEndToEndTest.java", "src/test/java/com/google/protobuf/MapForProto2Test.java", @@ -483,6 +487,7 @@ LITE_TEST_EXCLUSIONS = [ "src/test/java/com/google/protobuf/Proto2SchemaTest.java", "src/test/java/com/google/protobuf/Proto2UnknownEnumValueTest.java", "src/test/java/com/google/protobuf/RepeatedFieldBuilderV3Test.java", + "src/test/java/com/google/protobuf/RuntimeVersionTest.java", "src/test/java/com/google/protobuf/ServiceTest.java", "src/test/java/com/google/protobuf/SingleFieldBuilderV3Test.java", "src/test/java/com/google/protobuf/TestBadIdentifiers.java", diff --git a/java/core/pom.xml b/java/core/pom.xml index 84d674094e..c98d168792 100644 --- a/java/core/pom.xml +++ b/java/core/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.24.0 + 3.25.0 protobuf-java diff --git a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java index f383625b25..30eccc1eca 100644 --- a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java +++ b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java @@ -538,44 +538,4 @@ public abstract class AbstractMessage return (BuilderType) super.mergeFrom(input, extensionRegistry); } } - - /** - * @deprecated from v3.0.0-beta-3+, for compatibility with v2.5.0 and v2.6.1 - * generated code. - */ - @Deprecated - protected static int hashLong(long n) { - return (int) (n ^ (n >>> 32)); - } - - /** - * @deprecated from v3.0.0-beta-3+, for compatibility with v2.5.0 and v2.6.1 - * generated code. - */ - @Deprecated - protected static int hashBoolean(boolean b) { - return b ? 1231 : 1237; - } - - /** - * @deprecated from v3.0.0-beta-3+, for compatibility with v2.5.0 and v2.6.1 - * generated code. - */ - @Deprecated - protected static int hashEnum(EnumLite e) { - return e.getNumber(); - } - - /** - * @deprecated from v3.0.0-beta-3+, for compatibility with v2.5.0 and v2.6.1 - * generated code. - */ - @Deprecated - protected static int hashEnumList(List list) { - int hash = 1; - for (EnumLite e : list) { - hash = 31 * hash + hashEnum(e); - } - return hash; - } } diff --git a/java/core/src/main/java/com/google/protobuf/Descriptors.java b/java/core/src/main/java/com/google/protobuf/Descriptors.java index fb9b661bb0..a8ed0e8d91 100644 --- a/java/core/src/main/java/com/google/protobuf/Descriptors.java +++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java @@ -140,8 +140,6 @@ public final class Descriptors { } /** The syntax of the .proto file. */ - @Deprecated - public enum Syntax { UNKNOWN("unknown"), PROTO2("proto2"), @@ -156,8 +154,6 @@ public final class Descriptors { } /** Get the syntax of the .proto file. */ - @Deprecated - public Syntax getSyntax() { if (Syntax.PROTO3.name.equals(proto.getSyntax())) { return Syntax.PROTO3; @@ -605,6 +601,15 @@ public final class Descriptors { pool.addSymbol(message); } + /** + * This method is to be called by generated code only. It resolves features for the descriptor + * and all of its children. + * + *

TODO Implement and use this method in gencode once users using prebuilt jars + * with stale runtimes updated. + */ + public void resolveAllFeatures() {} + /** Look up and cross-link all field types, etc. */ private void crossLink() throws DescriptorValidationException { for (final Descriptor messageType : messageTypes) { @@ -1264,8 +1269,6 @@ public final class Descriptors { * Returns true if this field was syntactically written with "optional" in the .proto file. * Excludes singular proto3 fields that do not have a label. */ - @Deprecated - public boolean hasOptionalKeyword() { return isProto3Optional || (file.getSyntax() == Syntax.PROTO2 && isOptional() && getContainingOneof() == null); @@ -2834,8 +2837,6 @@ public final class Descriptors { return proto; } - @Deprecated - public boolean isSynthetic() { return fields.length == 1 && fields[0].isProto3Optional; } diff --git a/java/core/src/main/java/com/google/protobuf/FieldSet.java b/java/core/src/main/java/com/google/protobuf/FieldSet.java index d2a5d48fb8..a8ba1bd413 100644 --- a/java/core/src/main/java/com/google/protobuf/FieldSet.java +++ b/java/core/src/main/java/com/google/protobuf/FieldSet.java @@ -173,7 +173,8 @@ final class FieldSet> { /** Get a simple map containing all the fields. */ public Map getAllFields() { if (hasLazyField) { - SmallSortedMap result = cloneAllFieldsMap(fields, /* copyList */ false); + SmallSortedMap result = + cloneAllFieldsMap(fields, /* copyList= */ false, /* resolveLazyFields= */ true); if (fields.isImmutable()) { result.makeImmutable(); } @@ -183,22 +184,22 @@ final class FieldSet> { } private static > SmallSortedMap cloneAllFieldsMap( - SmallSortedMap fields, boolean copyList) { + SmallSortedMap fields, boolean copyList, boolean resolveLazyFields) { SmallSortedMap result = SmallSortedMap.newFieldMap(DEFAULT_FIELD_MAP_ARRAY_SIZE); for (int i = 0; i < fields.getNumArrayEntries(); i++) { - cloneFieldEntry(result, fields.getArrayEntryAt(i), copyList); + cloneFieldEntry(result, fields.getArrayEntryAt(i), copyList, resolveLazyFields); } for (Map.Entry entry : fields.getOverflowEntries()) { - cloneFieldEntry(result, entry, copyList); + cloneFieldEntry(result, entry, copyList, resolveLazyFields); } return result; } private static > void cloneFieldEntry( - Map map, Map.Entry entry, boolean copyList) { + Map map, Map.Entry entry, boolean copyList, boolean resolveLazyFields) { T key = entry.getKey(); Object value = entry.getValue(); - if (value instanceof LazyField) { + if (resolveLazyFields && value instanceof LazyField) { map.put(key, ((LazyField) value).getValue()); } else if (copyList && value instanceof List) { map.put(key, new ArrayList<>((List) value)); @@ -500,11 +501,12 @@ final class FieldSet> { private void mergeFromField(final Map.Entry entry) { final T descriptor = entry.getKey(); Object otherValue = entry.getValue(); - if (otherValue instanceof LazyField) { - otherValue = ((LazyField) otherValue).getValue(); - } + boolean isLazyField = otherValue instanceof LazyField; if (descriptor.isRepeated()) { + if (isLazyField) { + throw new IllegalStateException("Lazy fields can not be repeated"); + } Object value = getField(descriptor); if (value == null) { value = new ArrayList<>(); @@ -516,9 +518,17 @@ final class FieldSet> { } else if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) { Object value = getField(descriptor); if (value == null) { + // New field. fields.put(descriptor, cloneIfMutable(otherValue)); + if (isLazyField) { + hasLazyField = true; + } } else { - // Merge the messages. + // There is an existing field. Need to merge the messages. + if (otherValue instanceof LazyField) { + // Extract the actual value for lazy fields. + otherValue = ((LazyField) otherValue).getValue(); + } value = descriptor .internalMergeFrom(((MessageLite) value).toBuilder(), (MessageLite) otherValue) @@ -526,6 +536,9 @@ final class FieldSet> { fields.put(descriptor, value); } } else { + if (isLazyField) { + throw new IllegalStateException("Lazy fields must be message-valued"); + } fields.put(descriptor, cloneIfMutable(otherValue)); } } @@ -946,7 +959,8 @@ final class FieldSet> { SmallSortedMap fieldsForBuild = fields; if (hasNestedBuilders) { // Make a copy of the fields map with all Builders replaced by Message. - fieldsForBuild = cloneAllFieldsMap(fields, /* copyList */ false); + fieldsForBuild = + cloneAllFieldsMap(fields, /* copyList= */ false, /* resolveLazyFields= */ false); replaceBuilders(fieldsForBuild, partial); } FieldSet fieldSet = new FieldSet<>(fieldsForBuild); @@ -1018,7 +1032,10 @@ final class FieldSet> { /** Returns a new Builder using the fields from {@code fieldSet}. */ public static > Builder fromFieldSet(FieldSet fieldSet) { - Builder builder = new Builder(cloneAllFieldsMap(fieldSet.fields, /* copyList */ true)); + Builder builder = + new Builder( + cloneAllFieldsMap( + fieldSet.fields, /* copyList= */ true, /* resolveLazyFields= */ false)); builder.hasLazyField = fieldSet.hasLazyField; return builder; } @@ -1028,7 +1045,8 @@ final class FieldSet> { /** Get a simple map containing all the fields. */ public Map getAllFields() { if (hasLazyField) { - SmallSortedMap result = cloneAllFieldsMap(fields, /* copyList */ false); + SmallSortedMap result = + cloneAllFieldsMap(fields, /* copyList= */ false, /* resolveLazyFields= */ true); if (fields.isImmutable()) { result.makeImmutable(); } else { @@ -1069,7 +1087,7 @@ final class FieldSet> { private void ensureIsMutable() { if (!isMutable) { - fields = cloneAllFieldsMap(fields, /* copyList */ true); + fields = cloneAllFieldsMap(fields, /* copyList= */ true, /* resolveLazyFields= */ false); isMutable = true; } } @@ -1274,11 +1292,12 @@ final class FieldSet> { private void mergeFromField(final Map.Entry entry) { final T descriptor = entry.getKey(); Object otherValue = entry.getValue(); - if (otherValue instanceof LazyField) { - otherValue = ((LazyField) otherValue).getValue(); - } + boolean isLazyField = otherValue instanceof LazyField; if (descriptor.isRepeated()) { + if (isLazyField) { + throw new IllegalStateException("Lazy fields can not be repeated"); + } List value = (List) getFieldAllowBuilders(descriptor); if (value == null) { value = new ArrayList<>(); @@ -1290,9 +1309,17 @@ final class FieldSet> { } else if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) { Object value = getFieldAllowBuilders(descriptor); if (value == null) { + // New field. fields.put(descriptor, FieldSet.cloneIfMutable(otherValue)); + if (isLazyField) { + hasLazyField = true; + } } else { - // Merge the messages. + // There is an existing field. Need to merge the messages. + if (otherValue instanceof LazyField) { + // Extract the actual value for lazy fields. + otherValue = ((LazyField) otherValue).getValue(); + } if (value instanceof MessageLite.Builder) { descriptor.internalMergeFrom((MessageLite.Builder) value, (MessageLite) otherValue); } else { @@ -1304,6 +1331,9 @@ final class FieldSet> { } } } else { + if (isLazyField) { + throw new IllegalStateException("Lazy fields must be message-valued"); + } fields.put(descriptor, cloneIfMutable(otherValue)); } } diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java index c153960de9..115f4288cd 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java @@ -1440,7 +1440,7 @@ public abstract class GeneratedMessageLite< } catch (ClassNotFoundException e) { throw new RuntimeException("Unable to find proto buffer class: " + messageClassName, e); } catch (NoSuchFieldException e) { - return readResolveFallback(); + throw new RuntimeException("Unable to find DEFAULT_INSTANCE in " + messageClassName, e); } catch (SecurityException e) { throw new RuntimeException("Unable to call DEFAULT_INSTANCE in " + messageClassName, e); } catch (IllegalAccessException e) { @@ -1450,33 +1450,6 @@ public abstract class GeneratedMessageLite< } } - /** - * @deprecated from v3.0.0-beta-3+, for compatibility with v2.5.0 and v2.6.1 generated code. - */ - @Deprecated - private Object readResolveFallback() throws ObjectStreamException { - try { - Class messageClass = resolveMessageClass(); - java.lang.reflect.Field defaultInstanceField = - messageClass.getDeclaredField("defaultInstance"); - defaultInstanceField.setAccessible(true); - MessageLite defaultInstance = (MessageLite) defaultInstanceField.get(null); - return defaultInstance.newBuilderForType() - .mergeFrom(asBytes) - .buildPartial(); - } catch (ClassNotFoundException e) { - throw new RuntimeException("Unable to find proto buffer class: " + messageClassName, e); - } catch (NoSuchFieldException e) { - throw new RuntimeException("Unable to find defaultInstance in " + messageClassName, e); - } catch (SecurityException e) { - throw new RuntimeException("Unable to call defaultInstance in " + messageClassName, e); - } catch (IllegalAccessException e) { - throw new RuntimeException("Unable to call parsePartialFrom", e); - } catch (InvalidProtocolBufferException e) { - throw new RuntimeException("Unable to understand proto buffer", e); - } - } - private Class resolveMessageClass() throws ClassNotFoundException { return messageClass != null ? messageClass : Class.forName(messageClassName); } diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java index 9c4980fcbe..0a5bfda6bb 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java @@ -2459,11 +2459,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage implements Seri final String containingOneofCamelCaseName) { isOneofField = descriptor.getRealContainingOneof() != null; - hasHasMethod = - descriptor.getFile().getSyntax() == FileDescriptor.Syntax.EDITIONS && descriptor.hasPresence() - || descriptor.getFile().getSyntax() == FileDescriptor.Syntax.PROTO2 - || descriptor.hasOptionalKeyword() - || (!isOneofField && descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE); + hasHasMethod = descriptor.hasPresence(); ReflectionInvoker reflectionInvoker = new ReflectionInvoker( descriptor, diff --git a/java/core/src/main/java/com/google/protobuf/RuntimeVersion.java b/java/core/src/main/java/com/google/protobuf/RuntimeVersion.java new file mode 100644 index 0000000000..815bb9ed18 --- /dev/null +++ b/java/core/src/main/java/com/google/protobuf/RuntimeVersion.java @@ -0,0 +1,128 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +package com.google.protobuf; + +import java.util.logging.Logger; + +/** + * Provides the version of this Protobuf Java runtime, and methods for Protobuf Java gencode to + * validate that versions are compatible. Fields and methods in this class should be only accessed + * by related unit tests and Protobuf Java gencode, and should not be used elsewhere. + */ +public final class RuntimeVersion { + + /** Indicates the domain of the Protobuf artifact. */ + public enum RuntimeDomain { + GOOGLE_INTERNAL, + PUBLIC, + } + + // The version of this runtime. + // Automatically updated by Protobuf release process. Do not edit manually. + public static final RuntimeDomain DOMAIN = RuntimeDomain.PUBLIC; + public static final int MAJOR = 3; + public static final int MINOR = 26; + public static final int PATCH = 0; + public static final String SUFFIX = "-dev"; + private static final String VERSION_STRING = versionString(MAJOR, MINOR, PATCH, SUFFIX); + + /** + * Validates that the gencode is in the same domain as the runtime. + * + *

This method will be directly called by the google-internal gencode to verify no cross-domain + * usages. + * + * @param gencodeDomain the domain where Protobuf Java code was generated. + * @throws ProtobufRuntimeVersionException if gencodeDomain is not the same as DOMAIN. + */ + public static void validateProtobufGencodeDomain(RuntimeDomain gencodeDomain) { + // Check the environmental variable, and temporarily disable validation if it's set to true. + String disableFlag = java.lang.System.getenv("TEMORARILY_DISABLE_PROTOBUF_VERSION_CHECK"); + if ((disableFlag != null && disableFlag.equals("true"))) { + return; + } + + if (gencodeDomain != DOMAIN) { + throw new ProtobufRuntimeVersionException( + String.format( + "Mismatched Protobuf Gencode/Runtime domains: gencode %s, runtime %s. Cross-domain" + + " usage of Protobuf is not supported.", + gencodeDomain, DOMAIN)); + } + } + + /** + * Validates that the gencode version is compatible with this runtime version according to + * https://protobuf.dev/support/cross-version-runtime-guarantee/. + * + *

This method is currently only used by Protobuf Java gencode in OSS. + * + *

This method is only for Protobuf Java gencode; do not call it elsewhere. + * + * @param domain the domain where Protobuf Java code was generated. + * @param major the major version of Protobuf Java gencode. + * @param minor the minor version of Protobuf Java gencode. + * @param patch the micro/patch version of Protobuf Java gencode. + * @param suffix the version suffix e.g. "-rc2", "-dev", etc. + * @throws ProtobufRuntimeVersionException if versions are incompatible. + */ + public static void validateProtobufGencodeVersion( + RuntimeDomain domain, int major, int minor, int patch, String suffix) { + + // Check that version numbers are valid. + if (major < 0 || minor < 0 || patch < 0) { + throw new ProtobufRuntimeVersionException( + "Invalid gencode version: " + versionString(major, minor, patch, suffix)); + } + + validateProtobufGencodeDomain(domain); + + String gencodeVersionString = versionString(major, minor, patch, suffix); + // Check that runtime major version is the same as the gencode major version. + if (major != MAJOR) { + throw new ProtobufRuntimeVersionException( + String.format( + "Mismatched Protobuf Gencode/Runtime major versions: gencode %s, runtime %s. Same" + + " major version is required.", + gencodeVersionString, VERSION_STRING)); + } + + // Check that runtime version is newer than the gencode version. + if (MINOR < minor || (MINOR == minor && PATCH < patch)) { + throw new ProtobufRuntimeVersionException( + String.format( + "Protobuf Java runtime version cannot be older than the gencode version:" + + "gencode %s, runtime %s.", + gencodeVersionString, VERSION_STRING)); + } + + // Check that runtime version suffix is the same as the gencode version suffix. + if (!suffix.equals(SUFFIX)) { + throw new ProtobufRuntimeVersionException( + String.format( + "Mismatched Protobuf Gencode/Runtime version suffixes: gencode %s, runtime %s." + + " Version suffixes must be the same.", + gencodeVersionString, VERSION_STRING)); + } + } + + /** + * A runtime exception to be thrown by the version validator if version is not well defined or + * versions mismatch. + */ + public static final class ProtobufRuntimeVersionException extends RuntimeException { + public ProtobufRuntimeVersionException(String message) { + super(message); + } + } + + /** Gets the version string given the version segments. */ + private static String versionString(int major, int minor, int patch, String suffix) { + return String.format("%d.%d.%d%s", major, minor, patch, suffix); + } +} diff --git a/java/core/src/main/java/com/google/protobuf/TextFormat.java b/java/core/src/main/java/com/google/protobuf/TextFormat.java index a49919ef01..39838adc5f 100644 --- a/java/core/src/main/java/com/google/protobuf/TextFormat.java +++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java @@ -38,58 +38,6 @@ public final class TextFormat { private static final String DEBUG_STRING_SILENT_MARKER = "\t "; - /** - * Outputs a textual representation of the Protocol Message supplied into the parameter output. - * (This representation is the new version of the classic "ProtocolPrinter" output from the - * original Protocol Buffer system) - * - * @deprecated Use {@code printer().print(MessageOrBuilder, Appendable)} - */ - @Deprecated - @InlineMe( - replacement = "TextFormat.printer().print(message, output)", - imports = "com.google.protobuf.TextFormat") - public static void print(final MessageOrBuilder message, final Appendable output) - throws IOException { - printer().print(message, output); - } - - /** - * Outputs a textual representation of {@code fields} to {@code output}. - * - * @deprecated Use {@code printer().print(UnknownFieldSet, Appendable)} - */ - @Deprecated - public static void print(final UnknownFieldSet fields, final Appendable output) - throws IOException { - printer().print(fields, output); - } - - /** - * Same as {@code print()}, except that non-ASCII characters are not escaped. - * - * @deprecated Use {@code printer().escapingNonAscii(false).print(MessageOrBuilder, Appendable)} - */ - @Deprecated - @InlineMe( - replacement = "TextFormat.printer().escapingNonAscii(false).print(message, output)", - imports = "com.google.protobuf.TextFormat") - public static void printUnicode(final MessageOrBuilder message, final Appendable output) - throws IOException { - printer().escapingNonAscii(false).print(message, output); - } - - /** - * Same as {@code print()}, except that non-ASCII characters are not escaped. - * - * @deprecated Use {@code printer().escapingNonAscii(false).print(UnknownFieldSet, Appendable)} - */ - @Deprecated - public static void printUnicode(final UnknownFieldSet fields, final Appendable output) - throws IOException { - printer().escapingNonAscii(false).print(fields, output); - } - /** * Generates a human readable form of this message, useful for debugging and other purposes, with * no newline characters. This is just a trivial wrapper around {@link @@ -99,130 +47,6 @@ public final class TextFormat { return printer().shortDebugString(message); } - /** - * Generates a human readable form of the field, useful for debugging and other purposes, with - * no newline characters. - * - * @deprecated Use {@code printer().shortDebugString(FieldDescriptor, Object)} - */ - @Deprecated - public static String shortDebugString(final FieldDescriptor field, final Object value) { - return printer().shortDebugString(field, value); - } - - /** - * Generates a human readable form of the unknown fields, useful for debugging and other - * purposes, with no newline characters. - * - * @deprecated Use {@code printer().shortDebugString(UnknownFieldSet)} - */ - @Deprecated - public static String shortDebugString(final UnknownFieldSet fields) { - return printer().shortDebugString(fields); - } - - /** - * Like {@code print()}, but writes directly to a {@code String} and returns it. - * - * @deprecated Use {@code message.toString()} - */ - @Deprecated - @InlineMe( - replacement = "TextFormat.printer().printToString(message)", - imports = "com.google.protobuf.TextFormat") - public static String printToString(final MessageOrBuilder message) { - return printer().printToString(message); - } - - /** - * Like {@code print()}, but writes directly to a {@code String} and returns it. - * - * @deprecated Use {@link UnknownFieldSet#toString()} - */ - @Deprecated - public static String printToString(final UnknownFieldSet fields) { - return printer().printToString(fields); - } - - /** - * Same as {@code printToString()}, except that non-ASCII characters in string type fields are not - * escaped in backslash+octals. - * - * @deprecated Use {@code printer().escapingNonAscii(false).printToString(MessageOrBuilder)} - */ - @Deprecated - @InlineMe( - replacement = "TextFormat.printer().escapingNonAscii(false).printToString(message)", - imports = "com.google.protobuf.TextFormat") - public static String printToUnicodeString(final MessageOrBuilder message) { - return printer().escapingNonAscii(false).printToString(message); - } - - /** - * Same as {@code printToString()}, except that non-ASCII characters in string type fields are - * not escaped in backslash+octals. - * - * @deprecated Use {@code printer().escapingNonAscii(false).printToString(UnknownFieldSet)} - */ - @Deprecated - public static String printToUnicodeString(final UnknownFieldSet fields) { - return printer().escapingNonAscii(false).printToString(fields); - } - - /** @deprecated Use {@code printer().printField(FieldDescriptor, Object, Appendable)} */ - @Deprecated - public static void printField( - final FieldDescriptor field, final Object value, final Appendable output) - throws IOException { - printer().printField(field, value, output); - } - - /** @deprecated Use {@code printer().printFieldToString(FieldDescriptor, Object)} */ - @Deprecated - public static String printFieldToString(final FieldDescriptor field, final Object value) { - return printer().printFieldToString(field, value); - } - - /** - * Outputs a unicode textual representation of the value of given field value. - * - *

Same as {@code printFieldValue()}, except that non-ASCII characters in string type fields - * are not escaped in backslash+octals. - * - * @deprecated Use {@code printer().escapingNonAscii(false).printFieldValue(FieldDescriptor, - * Object, Appendable)} - * @param field the descriptor of the field - * @param value the value of the field - * @param output the output to which to append the formatted value - * @throws ClassCastException if the value is not appropriate for the given field descriptor - * @throws IOException if there is an exception writing to the output - */ - @Deprecated - public static void printUnicodeFieldValue( - final FieldDescriptor field, final Object value, final Appendable output) - throws IOException { - printer().escapingNonAscii(false).printFieldValue(field, value, output); - } - - /** - * Outputs a textual representation of the value of given field value. - * - * @deprecated Use {@code printer().printFieldValue(FieldDescriptor, Object, Appendable)} - * @param field the descriptor of the field - * @param value the value of the field - * @param output the output to which to append the formatted value - * @throws ClassCastException if the value is not appropriate for the given field descriptor - * @throws IOException if there is an exception writing to the output - */ - @Deprecated - @InlineMe( - replacement = "TextFormat.printer().printFieldValue(field, value, output)", - imports = "com.google.protobuf.TextFormat") - public static void printFieldValue( - final FieldDescriptor field, final Object value, final Appendable output) throws IOException { - printer().printFieldValue(field, value, output); - } - /** * Outputs a textual representation of the value of an unknown field. * @@ -283,16 +107,23 @@ public final class TextFormat { public static final class Printer { // Printer instance which escapes non-ASCII characters. - private static final Printer DEFAULT = new Printer(true, TypeRegistry.getEmptyTypeRegistry()); + private static final Printer DEFAULT = + new Printer( + true, TypeRegistry.getEmptyTypeRegistry(), ExtensionRegistryLite.getEmptyRegistry()); /** Whether to escape non ASCII characters with backslash and octal. */ private final boolean escapeNonAscii; private final TypeRegistry typeRegistry; + private final ExtensionRegistryLite extensionRegistry; - private Printer(boolean escapeNonAscii, TypeRegistry typeRegistry) { + private Printer( + boolean escapeNonAscii, + TypeRegistry typeRegistry, + ExtensionRegistryLite extensionRegistry) { this.escapeNonAscii = escapeNonAscii; this.typeRegistry = typeRegistry; + this.extensionRegistry = extensionRegistry; } /** @@ -305,7 +136,7 @@ public final class TextFormat { * with the escape mode set to the given parameter. */ public Printer escapingNonAscii(boolean escapeNonAscii) { - return new Printer(escapeNonAscii, typeRegistry); + return new Printer(escapeNonAscii, typeRegistry, extensionRegistry); } /** @@ -318,7 +149,20 @@ public final class TextFormat { if (this.typeRegistry != TypeRegistry.getEmptyTypeRegistry()) { throw new IllegalArgumentException("Only one typeRegistry is allowed."); } - return new Printer(escapeNonAscii, typeRegistry); + return new Printer(escapeNonAscii, typeRegistry, extensionRegistry); + } + + /** + * Creates a new {@link Printer} using the given extensionRegistry. The new Printer clones all + * other configurations from the current {@link Printer}. + * + * @throws IllegalArgumentException if a registry is already set. + */ + public Printer usingExtensionRegistry(ExtensionRegistryLite extensionRegistry) { + if (this.extensionRegistry != ExtensionRegistryLite.getEmptyRegistry()) { + throw new IllegalArgumentException("Only one extensionRegistry is allowed."); + } + return new Printer(escapeNonAscii, typeRegistry, extensionRegistry); } /** @@ -377,7 +221,7 @@ public final class TextFormat { return false; } contentBuilder = DynamicMessage.getDefaultInstance(contentType).newBuilderForType(); - contentBuilder.mergeFrom((ByteString) value); + contentBuilder.mergeFrom((ByteString) value, extensionRegistry); } catch (InvalidProtocolBufferException e) { // The value of Any is malformed. We cannot print it out nicely, so fallback to printing out // the type_url and value as bytes. Note that we fail open here to be consistent with diff --git a/java/core/src/test/java/com/google/protobuf/LazilyParsedMessageSetTest.java b/java/core/src/test/java/com/google/protobuf/LazilyParsedMessageSetTest.java new file mode 100644 index 0000000000..c41a381823 --- /dev/null +++ b/java/core/src/test/java/com/google/protobuf/LazilyParsedMessageSetTest.java @@ -0,0 +1,162 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +package com.google.protobuf; + +import static com.google.common.truth.Truth.assertThat; + +import protobuf_unittest.UnittestMset.RawMessageSet; +import protobuf_unittest.UnittestMset.TestMessageSetExtension1; +import protobuf_unittest.UnittestMset.TestMessageSetExtension2; +import protobuf_unittest.UnittestMset.TestMessageSetExtension3; +import proto2_wireformat_unittest.UnittestMsetWireFormat.TestMessageSet; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Tests related to handling of MessageSets with lazily parsed extensions. */ +@RunWith(JUnit4.class) +public class LazilyParsedMessageSetTest { + private static final int TYPE_ID_1 = + TestMessageSetExtension1.getDescriptor().getExtensions().get(0).getNumber(); + private static final int TYPE_ID_2 = + TestMessageSetExtension2.getDescriptor().getExtensions().get(0).getNumber(); + private static final int TYPE_ID_3 = + TestMessageSetExtension3.getDescriptor().getExtensions().get(0).getNumber(); + private static final ByteString CORRUPTED_MESSAGE_PAYLOAD = + ByteString.copyFrom(new byte[] {(byte) 0xff}); + + @Before + public void setUp() { + ExtensionRegistryLite.setEagerlyParseMessageSets(false); + } + + @Test + public void testParseAndUpdateMessageSet_unaccessedLazyFieldsAreNotLoaded() throws Exception { + ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance(); + extensionRegistry.add(TestMessageSetExtension1.messageSetExtension); + extensionRegistry.add(TestMessageSetExtension2.messageSetExtension); + extensionRegistry.add(TestMessageSetExtension3.messageSetExtension); + + // Set up a TestMessageSet with 2 extensions. The first extension has corrupted payload + // data. The test below makes sure that we never load this extension. If we ever do, then we + // will handle the exception and replace the value with the default empty message (this behavior + // is tested below in testLoadCorruptedLazyField_getsReplacedWithEmptyMessage). Later on we + // check that when we serialize the message set, we still have corrupted payload for the first + // extension. + RawMessageSet inputRaw = + RawMessageSet.newBuilder() + .addItem( + RawMessageSet.Item.newBuilder() + .setTypeId(TYPE_ID_1) + .setMessage(CORRUPTED_MESSAGE_PAYLOAD)) + .addItem( + RawMessageSet.Item.newBuilder() + .setTypeId(TYPE_ID_2) + .setMessage( + TestMessageSetExtension2.newBuilder().setStr("foo").build().toByteString())) + .build(); + + ByteString inputData = inputRaw.toByteString(); + + // Re-parse as a TestMessageSet, so that all extensions are lazy + TestMessageSet messageSet = TestMessageSet.parseFrom(inputData, extensionRegistry); + + // Update one extension and add a new one. + TestMessageSet.Builder builder = messageSet.toBuilder(); + builder.setExtension( + TestMessageSetExtension2.messageSetExtension, + TestMessageSetExtension2.newBuilder().setStr("bar").build()); + + // Call .build() in the middle of updating the builder. This triggers a codepath that we want to + // make sure preserves lazy fields. + TestMessageSet unusedIntermediateMessageSet = builder.build(); + + builder.setExtension( + TestMessageSetExtension3.messageSetExtension, + TestMessageSetExtension3.newBuilder().setRequiredInt(666).build()); + + TestMessageSet updatedMessageSet = builder.build(); + + // Check that hasExtension call does not load lazy fields. + assertThat(updatedMessageSet.hasExtension(TestMessageSetExtension1.messageSetExtension)) + .isTrue(); + + // Serialize. The first extension should still be unloaded and will get serialized using the + // same corrupted byte array. + ByteString outputData = updatedMessageSet.toByteString(); + + // Re-parse as RawMessageSet + RawMessageSet actualRaw = + RawMessageSet.parseFrom(outputData, ExtensionRegistry.getEmptyRegistry()); + + RawMessageSet expectedRaw = + RawMessageSet.newBuilder() + .addItem( + RawMessageSet.Item.newBuilder() + .setTypeId(TYPE_ID_1) + // This is the important part -- we want to make sure that the payload of the + // 1st extensions is the same corrupted byte array. If we ever load the + // extension during our manipulations above, then we would have replaced it with + // the default empty message. + .setMessage(CORRUPTED_MESSAGE_PAYLOAD)) + .addItem( + RawMessageSet.Item.newBuilder() + .setTypeId(TYPE_ID_2) + .setMessage( + TestMessageSetExtension2.newBuilder().setStr("bar").build().toByteString())) + .addItem( + RawMessageSet.Item.newBuilder() + .setTypeId(TYPE_ID_3) + .setMessage( + TestMessageSetExtension3.newBuilder() + .setRequiredInt(666) + .build() + .toByteString())) + .build(); + + assertThat(actualRaw).isEqualTo(expectedRaw); + } + + @Test + public void testLoadCorruptedLazyField_getsReplacedWithEmptyMessage() throws Exception { + ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance(); + extensionRegistry.add(TestMessageSetExtension1.messageSetExtension); + + RawMessageSet inputRaw = + RawMessageSet.newBuilder() + .addItem( + RawMessageSet.Item.newBuilder() + .setTypeId(TYPE_ID_1) + .setMessage(CORRUPTED_MESSAGE_PAYLOAD)) + .build(); + + ByteString inputData = inputRaw.toByteString(); + + // Re-parse as a TestMessageSet, so that all extensions are lazy + TestMessageSet messageSet = TestMessageSet.parseFrom(inputData, extensionRegistry); + + assertThat(messageSet.getExtension(TestMessageSetExtension1.messageSetExtension)) + .isEqualTo(TestMessageSetExtension1.getDefaultInstance()); + + // Serialize. The first extension should be serialized as an empty message. + ByteString outputData = messageSet.toByteString(); + + // Re-parse as RawMessageSet + RawMessageSet actualRaw = + RawMessageSet.parseFrom(outputData, ExtensionRegistry.getEmptyRegistry()); + + RawMessageSet expectedRaw = + RawMessageSet.newBuilder() + .addItem( + RawMessageSet.Item.newBuilder().setTypeId(TYPE_ID_1).setMessage(ByteString.empty())) + .build(); + + assertThat(actualRaw).isEqualTo(expectedRaw); + } +} diff --git a/java/core/src/test/java/com/google/protobuf/RuntimeVersionTest.java b/java/core/src/test/java/com/google/protobuf/RuntimeVersionTest.java new file mode 100644 index 0000000000..c30c9a6b7f --- /dev/null +++ b/java/core/src/test/java/com/google/protobuf/RuntimeVersionTest.java @@ -0,0 +1,138 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +package com.google.protobuf; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertThrows; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public final class RuntimeVersionTest { + + @Test + public void versionValidation_invalidVersionNumbers() { + RuntimeVersion.ProtobufRuntimeVersionException thrown = + assertThrows( + RuntimeVersion.ProtobufRuntimeVersionException.class, + () -> + RuntimeVersion.validateProtobufGencodeVersion( + RuntimeVersion.DOMAIN, 1, -2, -3, "")); + assertThat(thrown).hasMessageThat().contains("Invalid gencode version: 1.-2.-3"); + } + + @Test + public void versionValidation_crossDomainDisallowed() { + + RuntimeVersion.RuntimeDomain gencodeDomain = RuntimeVersion.RuntimeDomain.GOOGLE_INTERNAL; + RuntimeVersion.ProtobufRuntimeVersionException thrown = + assertThrows( + RuntimeVersion.ProtobufRuntimeVersionException.class, + () -> RuntimeVersion.validateProtobufGencodeDomain(gencodeDomain)); + assertThat(thrown).hasMessageThat().contains("Mismatched Protobuf Gencode/Runtime domains"); + } + + @Test + public void versionValidation_sameDomainAllowed() { + + RuntimeVersion.RuntimeDomain gencodeDomain = RuntimeVersion.RuntimeDomain.PUBLIC; + RuntimeVersion.validateProtobufGencodeDomain(gencodeDomain); + } + + @Test + public void versionValidation_mismatchingMajorDisallowed() { + int gencodeMajor = 1; + RuntimeVersion.ProtobufRuntimeVersionException thrown = + assertThrows( + RuntimeVersion.ProtobufRuntimeVersionException.class, + () -> + RuntimeVersion.validateProtobufGencodeVersion( + RuntimeVersion.DOMAIN, + gencodeMajor, + RuntimeVersion.MINOR, + RuntimeVersion.PATCH, + RuntimeVersion.SUFFIX)); + assertThat(thrown) + .hasMessageThat() + .contains("Mismatched Protobuf Gencode/Runtime major versions"); + } + + @Test + public void versionValidation_versionNumbersAllTheSameAllowed() { + RuntimeVersion.validateProtobufGencodeVersion( + RuntimeVersion.DOMAIN, + RuntimeVersion.MAJOR, + RuntimeVersion.MINOR, + RuntimeVersion.PATCH, + RuntimeVersion.SUFFIX); + } + + @Test + public void versionValidation_NewerRuntimeVersionAllowed() { + int gencodeMinor = RuntimeVersion.MINOR - 1; + RuntimeVersion.validateProtobufGencodeVersion( + RuntimeVersion.DOMAIN, + RuntimeVersion.MAJOR, + gencodeMinor, + RuntimeVersion.PATCH, + RuntimeVersion.SUFFIX); + } + + @Test + public void versionValidation_OlderRuntimeVersionDisallowed() { + int gencodeMinor = RuntimeVersion.MINOR + 1; + RuntimeVersion.ProtobufRuntimeVersionException thrown = + assertThrows( + RuntimeVersion.ProtobufRuntimeVersionException.class, + () -> + RuntimeVersion.validateProtobufGencodeVersion( + RuntimeVersion.DOMAIN, + RuntimeVersion.MAJOR, + gencodeMinor, + RuntimeVersion.PATCH, + RuntimeVersion.SUFFIX)); + assertThat(thrown) + .hasMessageThat() + .contains("Protobuf Java runtime version cannot be older than the gencode version"); + + int gencodePatch = RuntimeVersion.PATCH + 1; + thrown = + assertThrows( + RuntimeVersion.ProtobufRuntimeVersionException.class, + () -> + RuntimeVersion.validateProtobufGencodeVersion( + RuntimeVersion.DOMAIN, + RuntimeVersion.MAJOR, + RuntimeVersion.MINOR, + gencodePatch, + RuntimeVersion.SUFFIX)); + assertThat(thrown) + .hasMessageThat() + .contains("Protobuf Java runtime version cannot be older than the gencode version"); + } + + @Test + public void versionValidation_differentVesionSuffixDisallowed() { + String gencodeSuffix = "-test"; + RuntimeVersion.ProtobufRuntimeVersionException thrown = + assertThrows( + RuntimeVersion.ProtobufRuntimeVersionException.class, + () -> + RuntimeVersion.validateProtobufGencodeVersion( + RuntimeVersion.DOMAIN, + RuntimeVersion.MAJOR, + RuntimeVersion.MINOR, + RuntimeVersion.PATCH, + gencodeSuffix)); + assertThat(thrown) + .hasMessageThat() + .contains("Mismatched Protobuf Gencode/Runtime version suffixes"); + } +} diff --git a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java index d95ed4c8d9..695e3f58b3 100644 --- a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java +++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java @@ -11,6 +11,7 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static com.google.protobuf.TestUtil.TEST_REQUIRED_INITIALIZED; import static com.google.protobuf.TestUtil.TEST_REQUIRED_UNINITIALIZED; +import static protobuf_unittest.UnittestProto.optionalInt32Extension; import static org.junit.Assert.assertThrows; import com.google.protobuf.DescriptorProtos.DescriptorProto; @@ -623,6 +624,83 @@ public class TextFormatTest { assertThat(actual).isEqualTo(expected); } + @Test + public void testPrintAny_anyWithDynamicMessageContainingExtensionTreatedAsUnknown() + throws Exception { + Descriptor descriptor = + createDescriptorForAny( + FieldDescriptorProto.newBuilder() + .setName("type_url") + .setNumber(1) + .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) + .setType(FieldDescriptorProto.Type.TYPE_STRING) + .build(), + FieldDescriptorProto.newBuilder() + .setName("value") + .setNumber(2) + .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) + .setType(FieldDescriptorProto.Type.TYPE_BYTES) + .build()); + DynamicMessage testAny = + DynamicMessage.newBuilder(descriptor) + .setField( + descriptor.findFieldByNumber(1), + "type.googleapis.com/" + TestAllExtensions.getDescriptor().getFullName()) + .setField( + descriptor.findFieldByNumber(2), + TestAllExtensions.newBuilder() + .setExtension(optionalInt32Extension, 12345) + .build() + .toByteString()) + .build(); + String actual = + TextFormat.printer() + .usingTypeRegistry(TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build()) + .printToString(testAny); + String expected = "[type.googleapis.com/protobuf_unittest.TestAllExtensions] {\n 1: 12345\n}\n"; + assertThat(actual).isEqualTo(expected); + } + + @Test + public void testPrintAny_anyWithDynamicMessageContainingExtensionWithRegistry() throws Exception { + Descriptor descriptor = + createDescriptorForAny( + FieldDescriptorProto.newBuilder() + .setName("type_url") + .setNumber(1) + .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) + .setType(FieldDescriptorProto.Type.TYPE_STRING) + .build(), + FieldDescriptorProto.newBuilder() + .setName("value") + .setNumber(2) + .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL) + .setType(FieldDescriptorProto.Type.TYPE_BYTES) + .build()); + DynamicMessage testAny = + DynamicMessage.newBuilder(descriptor) + .setField( + descriptor.findFieldByNumber(1), + "type.googleapis.com/" + TestAllExtensions.getDescriptor().getFullName()) + .setField( + descriptor.findFieldByNumber(2), + TestAllExtensions.newBuilder() + .setExtension(optionalInt32Extension, 12345) + .build() + .toByteString()) + .build(); + String actual = + TextFormat.printer() + .usingTypeRegistry(TypeRegistry.newBuilder().add(TestAllTypes.getDescriptor()).build()) + .usingExtensionRegistry(TestUtil.getFullExtensionRegistry()) + .printToString(testAny); + String expected = + "[type.googleapis.com/protobuf_unittest.TestAllExtensions] {\n" + + " [protobuf_unittest.optional_int32_extension]: 12345\n" + + "}\n"; + assertThat(actual).isEqualTo(expected); + } + @Test public void testPrintAny_anyFromWithNoValueField() throws Exception { Descriptor descriptor = diff --git a/java/core/src/test/java/com/google/protobuf/WireFormatTest.java b/java/core/src/test/java/com/google/protobuf/WireFormatTest.java index 020409e9cf..bbf8d0cba6 100644 --- a/java/core/src/test/java/com/google/protobuf/WireFormatTest.java +++ b/java/core/src/test/java/com/google/protobuf/WireFormatTest.java @@ -25,6 +25,7 @@ import proto2_wireformat_unittest.UnittestMsetWireFormat.TestMessageSet; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.List; +import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -39,6 +40,13 @@ public class WireFormatTest { TestMessageSetExtension2.getDescriptor().getExtensions().get(0).getNumber(); private static final int UNKNOWN_TYPE_ID = 1550055; + @After + public void tearDown() { + // Whether to parse message sets eagerly is stored in a global static. Since some tests modify + // the value, make sure to reset it between test runs. + ExtensionRegistryLite.setEagerlyParseMessageSets(false); + } + @Test public void testSerialization() throws Exception { TestAllTypes message = TestUtil.getAllSet(); diff --git a/java/kotlin-lite/pom.xml b/java/kotlin-lite/pom.xml index 254eb8281b..bc4fb9ef7c 100644 --- a/java/kotlin-lite/pom.xml +++ b/java/kotlin-lite/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.24.0 + 3.25.0 protobuf-kotlin-lite diff --git a/java/kotlin/pom.xml b/java/kotlin/pom.xml index 354e65494c..3d26d8a311 100644 --- a/java/kotlin/pom.xml +++ b/java/kotlin/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.24.0 + 3.25.0 protobuf-kotlin diff --git a/java/lite.md b/java/lite.md index d8201e0468..fbaf1c8ed4 100644 --- a/java/lite.md +++ b/java/lite.md @@ -29,7 +29,7 @@ protobuf Java Lite runtime. If you are using Maven, include the following: com.google.protobuf protobuf-javalite - 3.24.0 + 3.25.0 ``` diff --git a/java/lite/pom.xml b/java/lite/pom.xml index 3b4ff82583..38621da3ff 100644 --- a/java/lite/pom.xml +++ b/java/lite/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.24.0 + 3.25.0 protobuf-javalite @@ -161,6 +161,7 @@ RawMessageInfo.java Reader.java RopeByteString.java + RuntimeVersion.java Schema.java SchemaFactory.java SchemaUtil.java @@ -224,6 +225,7 @@ Proto2SchemaTest.java Proto2UnknownEnumValueTest.java RepeatedFieldBuilderV3Test.java + RuntimeVersionTest.java ServiceTest.java SingleFieldBuilderV3Test.java TestBadIdentifiers.java diff --git a/java/osgi/OsgiWrapper.java b/java/osgi/OsgiWrapper.java index e917ae60f3..c0690eb944 100644 --- a/java/osgi/OsgiWrapper.java +++ b/java/osgi/OsgiWrapper.java @@ -55,6 +55,11 @@ public final class OsgiWrapper implements Callable { description = "The classpath that contains dependencies of the input jar, separated with :") private String classpath; + @Option( + names = {"--automatic_module_name"}, + description = "The automatic module name of the bundle") + private String automaticModuleName; + @Option( names = {"--bundle_copyright"}, description = "Copyright string for the bundle") @@ -106,6 +111,7 @@ public final class OsgiWrapper implements Callable { Analyzer analyzer = new Analyzer(); analyzer.setJar(bin); + analyzer.setProperty(Analyzer.AUTOMATIC_MODULE_NAME, automaticModuleName); analyzer.setProperty(Analyzer.BUNDLE_NAME, bundleName); analyzer.setProperty(Analyzer.BUNDLE_SYMBOLICNAME, bundleSymbolicName); analyzer.setProperty(Analyzer.BUNDLE_VERSION, bundleVersion); diff --git a/java/osgi/osgi.bzl b/java/osgi/osgi.bzl index 40ee0842a5..68600b5d7b 100644 --- a/java/osgi/osgi.bzl +++ b/java/osgi/osgi.bzl @@ -23,6 +23,7 @@ load("@rules_java//java:defs.bzl", "java_library") # which is probably sub-optimal. def osgi_java_library( name, + automatic_module_name, bundle_description, bundle_doc_url, bundle_license, @@ -119,6 +120,7 @@ def osgi_java_library( # Repackage the jar with an OSGI manifest _osgi_jar( name = name, + automatic_module_name = automatic_module_name, bundle_description = bundle_description, bundle_doc_url = bundle_doc_url, bundle_license = bundle_license, @@ -141,6 +143,7 @@ def _run_osgi_wrapper(ctx, input_jar, classpath_jars, output_jar): args.add_joined("--classpath", classpath_jars, join_with = ":") args.add("--input_jar", input_jar.path) args.add("--output_jar", output_jar.path) + args.add("--automatic_module_name", ctx.attr.automatic_module_name) args.add("--bundle_copyright", ctx.attr.bundle_copyright) args.add("--bundle_description", ctx.attr.bundle_description) args.add("--bundle_doc_url", ctx.attr.bundle_doc_url) @@ -215,6 +218,7 @@ _osgi_jar = rule( "output_jar": "lib%{name}.jar", }, attrs = { + "automatic_module_name": attr.string(), "bundle_copyright": attr.string(), "bundle_description": attr.string(), "bundle_doc_url": attr.string(), diff --git a/java/pom.xml b/java/pom.xml index 1deeca92a8..9e0a6992c0 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.24.0 + 3.25.0 pom Protocol Buffers [Parent] diff --git a/java/protoc/pom.xml b/java/protoc/pom.xml index eec6f636e7..34f8579c8b 100644 --- a/java/protoc/pom.xml +++ b/java/protoc/pom.xml @@ -8,7 +8,7 @@ com.google.protobuf protoc - 3.24.0 + 3.25.0 pom Protobuf Compiler diff --git a/java/util/BUILD.bazel b/java/util/BUILD.bazel index c6ab799a5d..c8b9e76697 100644 --- a/java/util/BUILD.bazel +++ b/java/util/BUILD.bazel @@ -26,6 +26,7 @@ protobuf_versioned_java_library( srcs = glob([ "src/main/java/com/google/protobuf/util/*.java", ]), + automatic_module_name = "com.google.protobuf.util", bundle_description = "Utilities for Protocol Buffers", bundle_name = "Protocol Buffers [Util]", bundle_symbolic_name = "com.google.protobuf.util", diff --git a/java/util/pom.xml b/java/util/pom.xml index f5c6380899..f25581be84 100644 --- a/java/util/pom.xml +++ b/java/util/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 3.24.0 + 3.25.0 protobuf-java-util diff --git a/lua/def.c b/lua/def.c index 9affe52c12..1f9ee1217b 100644 --- a/lua/def.c +++ b/lua/def.c @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "upb/reflection/def.h" diff --git a/lua/lua_proto_library.bzl b/lua/lua_proto_library.bzl index 579eca121b..0f80f81cef 100644 --- a/lua/lua_proto_library.bzl +++ b/lua/lua_proto_library.bzl @@ -1,4 +1,4 @@ -# Copyright (c) 2009-2021, Google LLC +# Copyright (c) 2023, Google LLC # All rights reserved. # # Use of this source code is governed by a BSD-style diff --git a/lua/main.c b/lua/main.c index 7f32209627..8df1a85e89 100644 --- a/lua/main.c +++ b/lua/main.c @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include #include diff --git a/lua/msg.c b/lua/msg.c index 7c0e0e7d24..c82dd86590 100644 --- a/lua/msg.c +++ b/lua/msg.c @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd /* * lupb_Message -- Message/Array/Map objects in Lua/C that wrap upb diff --git a/lua/test.proto b/lua/test.proto index 92bcd1c88c..b7a20e18a8 100644 --- a/lua/test.proto +++ b/lua/test.proto @@ -1,39 +1,16 @@ -// Protocol Buffers - Google's data interchange format +/// Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd syntax = "proto2"; -import "google/protobuf/timestamp.proto"; - package upb_lua_test; +import "google/protobuf/timestamp.proto"; + message MapTest { map map_string_double = 1; } diff --git a/lua/test_upb.lua b/lua/test_upb.lua index 8ebf82bd8e..14e00a8276 100644 --- a/lua/test_upb.lua +++ b/lua/test_upb.lua @@ -2,33 +2,10 @@ Protocol Buffers - Google's data interchange format Copyright 2023 Google LLC. All rights reserved. -https://developers.google.com/protocol-buffers/ - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google LLC nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Use of this source code is governed by a BSD-style +license that can be found in the LICENSE file or at +https://developers.google.com/open-source/licenses/bsd --]]-------------------------------------------------------------------------- diff --git a/lua/upb.c b/lua/upb.c index 4500fb4e75..e1e40613d4 100644 --- a/lua/upb.c +++ b/lua/upb.c @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd /* * require("lua") -- A Lua extension for upb. diff --git a/lua/upb.h b/lua/upb.h index 46ec9118c5..adb1c8269e 100644 --- a/lua/upb.h +++ b/lua/upb.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd /* * Shared definitions for upb Lua modules. diff --git a/lua/upb.lua b/lua/upb.lua index 35333097c6..8b3baca03c 100644 --- a/lua/upb.lua +++ b/lua/upb.lua @@ -1,29 +1,11 @@ --[[-------------------------------------------------------------------------- - Copyright (c) 2009-2021, Google LLC - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of Google LLC nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Protocol Buffers - Google's data interchange format +Copyright 2023 Google LLC. All rights reserved. + +Use of this source code is governed by a BSD-style +license that can be found in the LICENSE file or at +https://developers.google.com/open-source/licenses/bsd --]]-------------------------------------------------------------------------- diff --git a/lua/upbc.cc b/lua/upbc.cc index 4a274f22a5..bce4b7d284 100644 --- a/lua/upbc.cc +++ b/lua/upbc.cc @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "google/protobuf/descriptor.pb.h" #include "absl/strings/str_replace.h" diff --git a/objectivec/BUILD.bazel b/objectivec/BUILD.bazel index cb0d7c8034..d9e18ee1a5 100644 --- a/objectivec/BUILD.bazel +++ b/objectivec/BUILD.bazel @@ -160,6 +160,7 @@ objc_library( conformance_test( name = "conformance_test", failure_list = "//conformance:failure_list_objc.txt", + maximum_edition = "2023", target_compatible_with = ["@platforms//os:macos"], testee = "//conformance:conformance_objc", ) diff --git a/objectivec/GPBAny.pbobjc.h b/objectivec/GPBAny.pbobjc.h index c0d389f039..a9ae0c5304 100644 --- a/objectivec/GPBAny.pbobjc.h +++ b/objectivec/GPBAny.pbobjc.h @@ -168,6 +168,9 @@ GPB_FINAL @interface GPBAny : GPBMessage /** Must be a valid serialized protocol buffer of the above specified type. */ @property(nonatomic, readwrite, copy, null_resettable) NSData *value; +// NOTE: There are some Objective-C specific methods/properties in +// GPBWellKnownTypes.h that will likey be useful. + @end NS_ASSUME_NONNULL_END diff --git a/objectivec/GPBAny.pbobjc.m b/objectivec/GPBAny.pbobjc.m index be6ce4ed5e..65207e8293 100644 --- a/objectivec/GPBAny.pbobjc.m +++ b/objectivec/GPBAny.pbobjc.m @@ -3,6 +3,7 @@ // source: google/protobuf/any.proto #import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBWellKnownTypes.h" #import "GPBAny.pbobjc.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30007 @@ -39,6 +40,13 @@ static GPBFileDescription GPBAnyRoot_FileDescription = { .syntax = GPBFileSyntaxProto3 }; +// This is to help make sure that the GPBWellKnownTypes.* categories get linked and +// developers do not have to use the `-ObjC` linker flag. More information +// here: https://medium.com/ios-os-x-development/categories-in-static-libraries-78e41f8ddb96 +__attribute__((used)) static NSString* any_importCategories () { + return GPBWellKnownTypesErrorDomain; +} + #pragma mark - GPBAny @implementation GPBAny diff --git a/objectivec/GPBCodedOutputStream.m b/objectivec/GPBCodedOutputStream.m index 0eec4556d6..7f81821413 100644 --- a/objectivec/GPBCodedOutputStream.m +++ b/objectivec/GPBCodedOutputStream.m @@ -160,7 +160,14 @@ static void GPBWriteRawLittleEndian64(GPBOutputBufferState *state, int64_t value } - (void)dealloc { - [self flush]; + @try { + [self flush]; + } @catch (NSException *exception) { + // -dealloc methods cannot fail, so swallow any exceptions from flushing. +#if defined(DEBUG) && DEBUG + NSLog(@"GPBCodedOutputStream: Exception while flushing in dealloc: %@", exception); +#endif + } [state_.output close]; [state_.output release]; [buffer_ release]; diff --git a/objectivec/GPBDictionary.m b/objectivec/GPBDictionary.m index 4d7c08c1ee..a07a419f8b 100644 --- a/objectivec/GPBDictionary.m +++ b/objectivec/GPBDictionary.m @@ -1044,6 +1044,7 @@ void GPBDictionaryReadEntry(id mapDictionary, GPBCodedInputStream *stream, //% GPBCodedOutputStream *outputStream = [[GPBCodedOutputStream alloc] initWithData:data]; //% WriteDict##KEY_NAME##Field(outputStream, key->value##KEY_NAME, kMapKeyFieldNumber, keyDataType); //% WriteDictEnumField(outputStream, value, kMapValueFieldNumber, GPBDataTypeEnum); +//% [outputStream flush]; //% [outputStream release]; //% return data; //%} @@ -2788,6 +2789,7 @@ void GPBDictionaryReadEntry(id mapDictionary, GPBCodedInputStream *stream, GPBCodedOutputStream *outputStream = [[GPBCodedOutputStream alloc] initWithData:data]; WriteDictUInt32Field(outputStream, key->valueUInt32, kMapKeyFieldNumber, keyDataType); WriteDictEnumField(outputStream, value, kMapValueFieldNumber, GPBDataTypeEnum); + [outputStream flush]; [outputStream release]; return data; } @@ -4518,6 +4520,7 @@ void GPBDictionaryReadEntry(id mapDictionary, GPBCodedInputStream *stream, GPBCodedOutputStream *outputStream = [[GPBCodedOutputStream alloc] initWithData:data]; WriteDictInt32Field(outputStream, key->valueInt32, kMapKeyFieldNumber, keyDataType); WriteDictEnumField(outputStream, value, kMapValueFieldNumber, GPBDataTypeEnum); + [outputStream flush]; [outputStream release]; return data; } @@ -6248,6 +6251,7 @@ void GPBDictionaryReadEntry(id mapDictionary, GPBCodedInputStream *stream, GPBCodedOutputStream *outputStream = [[GPBCodedOutputStream alloc] initWithData:data]; WriteDictUInt64Field(outputStream, key->valueUInt64, kMapKeyFieldNumber, keyDataType); WriteDictEnumField(outputStream, value, kMapValueFieldNumber, GPBDataTypeEnum); + [outputStream flush]; [outputStream release]; return data; } @@ -7978,6 +7982,7 @@ void GPBDictionaryReadEntry(id mapDictionary, GPBCodedInputStream *stream, GPBCodedOutputStream *outputStream = [[GPBCodedOutputStream alloc] initWithData:data]; WriteDictInt64Field(outputStream, key->valueInt64, kMapKeyFieldNumber, keyDataType); WriteDictEnumField(outputStream, value, kMapValueFieldNumber, GPBDataTypeEnum); + [outputStream flush]; [outputStream release]; return data; } @@ -9768,6 +9773,7 @@ void GPBDictionaryReadEntry(id mapDictionary, GPBCodedInputStream *stream, GPBCodedOutputStream *outputStream = [[GPBCodedOutputStream alloc] initWithData:data]; WriteDictStringField(outputStream, key->valueString, kMapKeyFieldNumber, keyDataType); WriteDictEnumField(outputStream, value, kMapValueFieldNumber, GPBDataTypeEnum); + [outputStream flush]; [outputStream release]; return data; } @@ -11741,6 +11747,7 @@ void GPBDictionaryReadEntry(id mapDictionary, GPBCodedInputStream *stream, GPBCodedOutputStream *outputStream = [[GPBCodedOutputStream alloc] initWithData:data]; WriteDictBoolField(outputStream, key->valueBool, kMapKeyFieldNumber, keyDataType); WriteDictEnumField(outputStream, value, kMapValueFieldNumber, GPBDataTypeEnum); + [outputStream flush]; [outputStream release]; return data; } diff --git a/objectivec/GPBDuration.pbobjc.h b/objectivec/GPBDuration.pbobjc.h index 9e67afc058..c5e27e4e5a 100644 --- a/objectivec/GPBDuration.pbobjc.h +++ b/objectivec/GPBDuration.pbobjc.h @@ -123,6 +123,9 @@ GPB_FINAL @interface GPBDuration : GPBMessage **/ @property(nonatomic, readwrite) int32_t nanos; +// NOTE: There are some Objective-C specific methods/properties in +// GPBWellKnownTypes.h that will likey be useful. + @end NS_ASSUME_NONNULL_END diff --git a/objectivec/GPBDuration.pbobjc.m b/objectivec/GPBDuration.pbobjc.m index f53c022d9d..124342f5e5 100644 --- a/objectivec/GPBDuration.pbobjc.m +++ b/objectivec/GPBDuration.pbobjc.m @@ -3,6 +3,7 @@ // source: google/protobuf/duration.proto #import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBWellKnownTypes.h" #import "GPBDuration.pbobjc.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30007 @@ -39,6 +40,13 @@ static GPBFileDescription GPBDurationRoot_FileDescription = { .syntax = GPBFileSyntaxProto3 }; +// This is to help make sure that the GPBWellKnownTypes.* categories get linked and +// developers do not have to use the `-ObjC` linker flag. More information +// here: https://medium.com/ios-os-x-development/categories-in-static-libraries-78e41f8ddb96 +__attribute__((used)) static NSString* duration_importCategories () { + return GPBWellKnownTypesErrorDomain; +} + #pragma mark - GPBDuration @implementation GPBDuration diff --git a/objectivec/GPBMessage.m b/objectivec/GPBMessage.m index 64c22dd840..e2436a226a 100644 --- a/objectivec/GPBMessage.m +++ b/objectivec/GPBMessage.m @@ -1343,6 +1343,7 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) { GPBCodedOutputStream *stream = [[GPBCodedOutputStream alloc] initWithData:data]; @try { [self writeToCodedOutputStream:stream]; + [stream flush]; } @catch (NSException *exception) { // This really shouldn't happen. Normally, this could mean there was a bug in the library and it // failed to match between computing the size and writing out the bytes. However, the more @@ -1369,6 +1370,7 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) { GPBCodedOutputStream *stream = [[GPBCodedOutputStream alloc] initWithData:data]; @try { [self writeDelimitedToCodedOutputStream:stream]; + [stream flush]; } @catch (NSException *exception) { // This really shouldn't happen. Normally, this could mean there was a bug in the library and it // failed to match between computing the size and writing out the bytes. However, the more @@ -1380,8 +1382,9 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) { NSLog(@"%@: Internal exception while building message delimitedData: %@", [self class], exception); #endif - // If it happens, truncate. - data.length = 0; + // If it happens, return an empty data. + [stream release]; + return [NSData data]; } [stream release]; return data; @@ -1391,6 +1394,7 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) { GPBCodedOutputStream *stream = [[GPBCodedOutputStream alloc] initWithOutputStream:output]; @try { [self writeToCodedOutputStream:stream]; + [stream flush]; size_t bytesWritten = [stream bytesWritten]; if (bytesWritten > kMaximumMessageSize) { [NSException raise:GPBMessageExceptionMessageTooLarge @@ -1434,6 +1438,7 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) { GPBCodedOutputStream *codedOutput = [[GPBCodedOutputStream alloc] initWithOutputStream:output]; @try { [self writeDelimitedToCodedOutputStream:codedOutput]; + [codedOutput flush]; } @finally { [codedOutput release]; } diff --git a/objectivec/GPBTimestamp.pbobjc.h b/objectivec/GPBTimestamp.pbobjc.h index 510ecc0316..bdf8ee4186 100644 --- a/objectivec/GPBTimestamp.pbobjc.h +++ b/objectivec/GPBTimestamp.pbobjc.h @@ -152,6 +152,9 @@ GPB_FINAL @interface GPBTimestamp : GPBMessage **/ @property(nonatomic, readwrite) int32_t nanos; +// NOTE: There are some Objective-C specific methods/properties in +// GPBWellKnownTypes.h that will likey be useful. + @end NS_ASSUME_NONNULL_END diff --git a/objectivec/GPBTimestamp.pbobjc.m b/objectivec/GPBTimestamp.pbobjc.m index f2b44fdef8..faf201519b 100644 --- a/objectivec/GPBTimestamp.pbobjc.m +++ b/objectivec/GPBTimestamp.pbobjc.m @@ -3,6 +3,7 @@ // source: google/protobuf/timestamp.proto #import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBWellKnownTypes.h" #import "GPBTimestamp.pbobjc.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30007 @@ -39,6 +40,13 @@ static GPBFileDescription GPBTimestampRoot_FileDescription = { .syntax = GPBFileSyntaxProto3 }; +// This is to help make sure that the GPBWellKnownTypes.* categories get linked and +// developers do not have to use the `-ObjC` linker flag. More information +// here: https://medium.com/ios-os-x-development/categories-in-static-libraries-78e41f8ddb96 +__attribute__((used)) static NSString* timestamp_importCategories () { + return GPBWellKnownTypesErrorDomain; +} + #pragma mark - GPBTimestamp @implementation GPBTimestamp diff --git a/objectivec/GPBUnknownFieldSet.m b/objectivec/GPBUnknownFieldSet.m index a68b62c841..768734070d 100644 --- a/objectivec/GPBUnknownFieldSet.m +++ b/objectivec/GPBUnknownFieldSet.m @@ -207,6 +207,7 @@ static void GPBUnknownFieldSetSerializedSizeAsMessageSet(__unused const void *ke NSMutableData *data = [NSMutableData dataWithLength:self.serializedSize]; GPBCodedOutputStream *output = [[GPBCodedOutputStream alloc] initWithData:data]; [self writeToCodedOutputStream:output]; + [output flush]; [output release]; return data; } diff --git a/objectivec/GPBWellKnownTypes.h b/objectivec/GPBWellKnownTypes.h index 732cafb32f..4cf5bcffd8 100644 --- a/objectivec/GPBWellKnownTypes.h +++ b/objectivec/GPBWellKnownTypes.h @@ -201,6 +201,24 @@ typedef NS_ENUM(NSInteger, GPBWellKnownTypesErrorCode) { */ - (nullable GPBMessage *)unpackMessageClass:(Class)messageClass error:(NSError **)errorPtr; +/** + * Unpacks the serialized message as if it was an instance of the given class. + * + * @note When checking type_url, the base URL is not checked, only the fully + * qualified name. + * + * @param messageClass The class to use to deserialize the contained message. + * @param extensionRegistry The extension registry to use to look up extensions. + * @param errorPtr Pointer to an error that will be populated if something + * goes wrong. + * + * @return An instance of the given class populated with the contained data, or + * nil on failure. + */ +- (nullable GPBMessage *)unpackMessageClass:(Class)messageClass + extensionRegistry:(nullable id)extensionRegistry + error:(NSError **)errorPtr; + @end NS_ASSUME_NONNULL_END diff --git a/objectivec/GPBWellKnownTypes.m b/objectivec/GPBWellKnownTypes.m index 097c5ca113..b212813208 100644 --- a/objectivec/GPBWellKnownTypes.m +++ b/objectivec/GPBWellKnownTypes.m @@ -195,6 +195,12 @@ static NSString *ParseTypeFromURL(NSString *typeURLString) { } - (GPBMessage *)unpackMessageClass:(Class)messageClass error:(NSError **)errorPtr { + return [self unpackMessageClass:messageClass extensionRegistry:nil error:errorPtr]; +} + +- (nullable GPBMessage *)unpackMessageClass:(Class)messageClass + extensionRegistry:(nullable id)extensionRegistry + error:(NSError **)errorPtr { NSString *fullName = [messageClass descriptor].fullName; if (fullName.length == 0) { if (errorPtr) { @@ -215,10 +221,7 @@ static NSString *ParseTypeFromURL(NSString *typeURLString) { return nil; } - // Any is proto3, which means no extensions, so this assumes anything put - // within an any also won't need extensions. A second helper could be added - // if needed. - return [messageClass parseFromData:self.value error:errorPtr]; + return [messageClass parseFromData:self.value extensionRegistry:extensionRegistry error:errorPtr]; } @end diff --git a/objectivec/Tests/GPBCodedOutputStreamTests.m b/objectivec/Tests/GPBCodedOutputStreamTests.m index e781c25c71..550864995f 100644 --- a/objectivec/Tests/GPBCodedOutputStreamTests.m +++ b/objectivec/Tests/GPBCodedOutputStreamTests.m @@ -393,4 +393,27 @@ NSException, GPBCodedOutputStreamException_WriteFailed); } +- (void)testThatDeallocNeverThrows { + uint8_t buffer[1] = {0}; + + // Output stream which can write precisely 1 byte of data before it's full. + NSOutputStream* output = [[[NSOutputStream alloc] initToBuffer:buffer + capacity:sizeof(buffer)] autorelease]; + + NSMutableData* outputBuffer = [NSMutableData data]; + GPBCodedOutputStream* codedOutput = + [[GPBCodedOutputStream alloc] initWithOutputStream:output data:outputBuffer]; + + [codedOutput writeRawByte:0x23]; + [codedOutput flush]; + + // Put one more byte in the output buffer. + [codedOutput writeRawByte:0x42]; + XCTAssertThrowsSpecificNamed([codedOutput flush], NSException, + GPBCodedOutputStreamException_WriteFailed); + + // -dealloc must not throw when it flushes, even if a previous flush failed. + XCTAssertNoThrow([codedOutput release]); +} + @end diff --git a/objectivec/Tests/GPBMessageTests.m b/objectivec/Tests/GPBMessageTests.m index d5a085c83d..d598a48b60 100644 --- a/objectivec/Tests/GPBMessageTests.m +++ b/objectivec/Tests/GPBMessageTests.m @@ -2225,4 +2225,17 @@ XCTAssertNil(shouldGetAPrefixMessage); } +- (void)testWriteToFullOutputStreamShouldThrow { + uint8_t buffer[1] = {0}; + + // Output stream which can write precisely 1 byte of data before it's full. + NSOutputStream *output = [[[NSOutputStream alloc] initToBuffer:buffer + capacity:sizeof(buffer)] autorelease]; + + TestAllTypes *message = [TestAllTypes message]; + [message setOptionalInt32:1]; + XCTAssertThrowsSpecificNamed([message writeToOutputStream:output], NSException, + GPBCodedOutputStreamException_WriteFailed); +} + @end diff --git a/php/BUILD.bazel b/php/BUILD.bazel index 345d1ab9b1..5518e564bd 100644 --- a/php/BUILD.bazel +++ b/php/BUILD.bazel @@ -4,10 +4,10 @@ load("@rules_pkg//:mappings.bzl", "pkg_filegroup", "pkg_files", "strip_prefix") load("@rules_pkg//:pkg.bzl", "pkg_tar") -load("//upb/cmake:build_defs.bzl", "staleness_test") +load("//:protobuf_version.bzl", "PROTOBUF_PHP_VERSION", "PROTOC_VERSION") load("//build_defs:internal_shell.bzl", "inline_sh_binary") load("//conformance:defs.bzl", "conformance_test") -load("//:protobuf_version.bzl", "PROTOBUF_PHP_VERSION", "PROTOC_VERSION") +load("//upb/cmake:build_defs.bzl", "staleness_test") filegroup( name = "source_files", @@ -32,7 +32,7 @@ inline_sh_binary( name = "build_extension", cmd = """ mkdir -p php/ext/google/protobuf/third_party/utf8_range - cp external/utf8_range/* php/ext/google/protobuf/third_party/utf8_range + cp third_party/utf8_range/* php/ext/google/protobuf/third_party/utf8_range pushd php/ext/google/protobuf phpize @@ -46,7 +46,7 @@ genrule( name = "extension", srcs = [ ":source_files", - "@utf8_range//:utf8_range_srcs", + "//third_party/utf8_range:utf8_range_srcs", ], outs = ["protobuf.so"], cmd = """ @@ -157,8 +157,8 @@ pkg_files( pkg_files( name = "utf8_range_files", srcs = [ - "@utf8_range//:LICENSE", - "@utf8_range//:utf8_range_srcs", + "//third_party/utf8_range:LICENSE", + "//third_party/utf8_range:utf8_range_srcs", ], prefix = "third_party/utf8_range", ) diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index af7cfc6cf1..979f226fc9 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -400,11 +400,8 @@ static zval* Message_get_property_ptr_ptr(zend_object* object, static zend_object* Message_clone_obj(zend_object* object) { Message* intern = (Message*)object; const upb_MiniTable* t = upb_MessageDef_MiniTable(intern->desc->msgdef); - upb_Message* clone = upb_Message_New(t, Arena_Get(&intern->arena)); - - // TODO: copy unknown fields? - // TODO: use official upb msg copy function - memcpy(clone, intern->msg, t->size); + upb_Message* clone = + upb_Message_ShallowClone(intern->msg, t, Arena_Get(&intern->arena)); zval ret; Message_GetPhpWrapper(&ret, intern->desc, clone, &intern->arena); return Z_OBJ_P(&ret); diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index f999768b48..31487a514d 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -181,6 +181,12 @@ Error, UINTPTR_MAX is undefined #define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only +#ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY +#define UPB_ONLYBITS(x) x +#else +#define UPB_ONLYBITS(x) UPB_PRIVATE(x) +#endif + /* Configure whether fasttable is switched on or not. *************************/ #ifdef __has_attribute @@ -319,8 +325,13 @@ void __asan_unpoison_memory_region(void const volatile *addr, size_t size); #if defined(UPB_IS_GOOGLE3) && !defined(UPB_BOOTSTRAP_STAGE0) #define UPB_DESC(sym) proto2_##sym +#define UPB_DESC_MINITABLE(sym) &proto2__##sym##_msg_init +#elif defined(UPB_BOOTSTRAP_STAGE0) +#define UPB_DESC(sym) google_protobuf_##sym +#define UPB_DESC_MINITABLE(sym) google__protobuf__##sym##_msg_init() #else #define UPB_DESC(sym) google_protobuf_##sym +#define UPB_DESC_MINITABLE(sym) &google__protobuf__##sym##_msg_init #endif @@ -387,7 +398,7 @@ void upb_Status_VAppendErrorFormat(upb_Status* status, const char* fmt, // Must be last. static const upb_MiniTableSub google_protobuf_FileDescriptorSet_submsgs[1] = { - {.submsg = &google__protobuf__FileDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FileDescriptorProto_msg_init}, }; static const upb_MiniTableField google_protobuf_FileDescriptorSet__fields[1] = { @@ -405,13 +416,13 @@ const upb_MiniTable google__protobuf__FileDescriptorSet_msg_init = { }; static const upb_MiniTableSub google_protobuf_FileDescriptorProto_submsgs[7] = { - {.submsg = &google__protobuf__DescriptorProto_msg_init}, - {.submsg = &google__protobuf__EnumDescriptorProto_msg_init}, - {.submsg = &google__protobuf__ServiceDescriptorProto_msg_init}, - {.submsg = &google__protobuf__FieldDescriptorProto_msg_init}, - {.submsg = &google__protobuf__FileOptions_msg_init}, - {.submsg = &google__protobuf__SourceCodeInfo_msg_init}, - {.subenum = &google_protobuf_Edition_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__DescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__ServiceDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FileOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__SourceCodeInfo_msg_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_Edition_enum_init}, }; static const upb_MiniTableField google_protobuf_FileDescriptorProto__fields[13] = { @@ -455,14 +466,14 @@ const upb_MiniTable google__protobuf__FileDescriptorProto_msg_init = { }; static const upb_MiniTableSub google_protobuf_DescriptorProto_submsgs[8] = { - {.submsg = &google__protobuf__FieldDescriptorProto_msg_init}, - {.submsg = &google__protobuf__DescriptorProto_msg_init}, - {.submsg = &google__protobuf__EnumDescriptorProto_msg_init}, - {.submsg = &google__protobuf__DescriptorProto__ExtensionRange_msg_init}, - {.submsg = &google__protobuf__FieldDescriptorProto_msg_init}, - {.submsg = &google__protobuf__MessageOptions_msg_init}, - {.submsg = &google__protobuf__OneofDescriptorProto_msg_init}, - {.submsg = &google__protobuf__DescriptorProto__ReservedRange_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__DescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__DescriptorProto__ExtensionRange_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__MessageOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__OneofDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__DescriptorProto__ReservedRange_msg_init}, }; static const upb_MiniTableField google_protobuf_DescriptorProto__fields[10] = { @@ -503,7 +514,7 @@ const upb_MiniTable google__protobuf__DescriptorProto_msg_init = { }; static const upb_MiniTableSub google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = { - {.submsg = &google__protobuf__ExtensionRangeOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__ExtensionRangeOptions_msg_init}, }; static const upb_MiniTableField google_protobuf_DescriptorProto_ExtensionRange__fields[3] = { @@ -542,10 +553,10 @@ const upb_MiniTable google__protobuf__DescriptorProto__ReservedRange_msg_init = }; static const upb_MiniTableSub google_protobuf_ExtensionRangeOptions_submsgs[4] = { - {.submsg = &google__protobuf__ExtensionRangeOptions__Declaration_msg_init}, - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, - {.subenum = &google_protobuf_ExtensionRangeOptions_VerificationState_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__ExtensionRangeOptions__Declaration_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_ExtensionRangeOptions_VerificationState_enum_init}, }; static const upb_MiniTableField google_protobuf_ExtensionRangeOptions__fields[4] = { @@ -620,9 +631,9 @@ const upb_MiniTable google__protobuf__ExtensionRangeOptions__Declaration_msg_ini }; static const upb_MiniTableSub google_protobuf_FieldDescriptorProto_submsgs[3] = { - {.submsg = &google__protobuf__FieldOptions_msg_init}, - {.subenum = &google_protobuf_FieldDescriptorProto_Label_enum_init}, - {.subenum = &google_protobuf_FieldDescriptorProto_Type_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldOptions_msg_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FieldDescriptorProto_Label_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FieldDescriptorProto_Type_enum_init}, }; static const upb_MiniTableField google_protobuf_FieldDescriptorProto__fields[11] = { @@ -680,7 +691,7 @@ const upb_MiniTable google__protobuf__FieldDescriptorProto_msg_init = { }; static const upb_MiniTableSub google_protobuf_OneofDescriptorProto_submsgs[1] = { - {.submsg = &google__protobuf__OneofOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__OneofOptions_msg_init}, }; static const upb_MiniTableField google_protobuf_OneofDescriptorProto__fields[2] = { @@ -701,9 +712,9 @@ const upb_MiniTable google__protobuf__OneofDescriptorProto_msg_init = { }; static const upb_MiniTableSub google_protobuf_EnumDescriptorProto_submsgs[3] = { - {.submsg = &google__protobuf__EnumValueDescriptorProto_msg_init}, - {.submsg = &google__protobuf__EnumOptions_msg_init}, - {.submsg = &google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumValueDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init}, }; static const upb_MiniTableField google_protobuf_EnumDescriptorProto__fields[5] = { @@ -748,7 +759,7 @@ const upb_MiniTable google__protobuf__EnumDescriptorProto__EnumReservedRange_msg }; static const upb_MiniTableSub google_protobuf_EnumValueDescriptorProto_submsgs[1] = { - {.submsg = &google__protobuf__EnumValueOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumValueOptions_msg_init}, }; static const upb_MiniTableField google_protobuf_EnumValueDescriptorProto__fields[3] = { @@ -770,8 +781,8 @@ const upb_MiniTable google__protobuf__EnumValueDescriptorProto_msg_init = { }; static const upb_MiniTableSub google_protobuf_ServiceDescriptorProto_submsgs[2] = { - {.submsg = &google__protobuf__MethodDescriptorProto_msg_init}, - {.submsg = &google__protobuf__ServiceOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__MethodDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__ServiceOptions_msg_init}, }; static const upb_MiniTableField google_protobuf_ServiceDescriptorProto__fields[3] = { @@ -793,7 +804,7 @@ const upb_MiniTable google__protobuf__ServiceDescriptorProto_msg_init = { }; static const upb_MiniTableSub google_protobuf_MethodDescriptorProto_submsgs[1] = { - {.submsg = &google__protobuf__MethodOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__MethodOptions_msg_init}, }; static const upb_MiniTableField google_protobuf_MethodDescriptorProto__fields[6] = { @@ -822,9 +833,9 @@ const upb_MiniTable google__protobuf__MethodDescriptorProto_msg_init = { }; static const upb_MiniTableSub google_protobuf_FileOptions_submsgs[3] = { - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, - {.subenum = &google_protobuf_FileOptions_OptimizeMode_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FileOptions_OptimizeMode_enum_init}, }; static const upb_MiniTableField google_protobuf_FileOptions__fields[22] = { @@ -893,8 +904,8 @@ const upb_MiniTable google__protobuf__FileOptions_msg_init = { }; static const upb_MiniTableSub google_protobuf_MessageOptions_submsgs[2] = { - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, }; static const upb_MiniTableField google_protobuf_MessageOptions__fields[7] = { @@ -948,13 +959,13 @@ const upb_MiniTable google__protobuf__MessageOptions_msg_init = { }; static const upb_MiniTableSub google_protobuf_FieldOptions_submsgs[7] = { - {.submsg = &google__protobuf__FieldOptions__EditionDefault_msg_init}, - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, - {.subenum = &google_protobuf_FieldOptions_CType_enum_init}, - {.subenum = &google_protobuf_FieldOptions_JSType_enum_init}, - {.subenum = &google_protobuf_FieldOptions_OptionRetention_enum_init}, - {.subenum = &google_protobuf_FieldOptions_OptionTargetType_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldOptions__EditionDefault_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FieldOptions_CType_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FieldOptions_JSType_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FieldOptions_OptionRetention_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FieldOptions_OptionTargetType_enum_init}, }; static const upb_MiniTableField google_protobuf_FieldOptions__fields[13] = { @@ -1014,7 +1025,7 @@ const upb_MiniTable google__protobuf__FieldOptions_msg_init = { }; static const upb_MiniTableSub google_protobuf_FieldOptions_EditionDefault_submsgs[1] = { - {.subenum = &google_protobuf_Edition_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_Edition_enum_init}, }; static const upb_MiniTableField google_protobuf_FieldOptions_EditionDefault__fields[2] = { @@ -1035,8 +1046,8 @@ const upb_MiniTable google__protobuf__FieldOptions__EditionDefault_msg_init = { }; static const upb_MiniTableSub google_protobuf_OneofOptions_submsgs[2] = { - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, }; static const upb_MiniTableField google_protobuf_OneofOptions__fields[2] = { @@ -1085,8 +1096,8 @@ const upb_MiniTable google__protobuf__OneofOptions_msg_init = { }; static const upb_MiniTableSub google_protobuf_EnumOptions_submsgs[2] = { - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, }; static const upb_MiniTableField google_protobuf_EnumOptions__fields[5] = { @@ -1138,8 +1149,8 @@ const upb_MiniTable google__protobuf__EnumOptions_msg_init = { }; static const upb_MiniTableSub google_protobuf_EnumValueOptions_submsgs[2] = { - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, }; static const upb_MiniTableField google_protobuf_EnumValueOptions__fields[4] = { @@ -1190,8 +1201,8 @@ const upb_MiniTable google__protobuf__EnumValueOptions_msg_init = { }; static const upb_MiniTableSub google_protobuf_ServiceOptions_submsgs[2] = { - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, }; static const upb_MiniTableField google_protobuf_ServiceOptions__fields[3] = { @@ -1241,9 +1252,9 @@ const upb_MiniTable google__protobuf__ServiceOptions_msg_init = { }; static const upb_MiniTableSub google_protobuf_MethodOptions_submsgs[3] = { - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, - {.subenum = &google_protobuf_MethodOptions_IdempotencyLevel_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_MethodOptions_IdempotencyLevel_enum_init}, }; static const upb_MiniTableField google_protobuf_MethodOptions__fields[4] = { @@ -1294,7 +1305,7 @@ const upb_MiniTable google__protobuf__MethodOptions_msg_init = { }; static const upb_MiniTableSub google_protobuf_UninterpretedOption_submsgs[1] = { - {.submsg = &google__protobuf__UninterpretedOption__NamePart_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption__NamePart_msg_init}, }; static const upb_MiniTableField google_protobuf_UninterpretedOption__fields[7] = { @@ -1349,12 +1360,12 @@ const upb_MiniTable google__protobuf__UninterpretedOption__NamePart_msg_init = { }; static const upb_MiniTableSub google_protobuf_FeatureSet_submsgs[6] = { - {.subenum = &google_protobuf_FeatureSet_FieldPresence_enum_init}, - {.subenum = &google_protobuf_FeatureSet_EnumType_enum_init}, - {.subenum = &google_protobuf_FeatureSet_RepeatedFieldEncoding_enum_init}, - {.subenum = &google_protobuf_FeatureSet_Utf8Validation_enum_init}, - {.subenum = &google_protobuf_FeatureSet_MessageEncoding_enum_init}, - {.subenum = &google_protobuf_FeatureSet_JsonFormat_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FeatureSet_FieldPresence_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FeatureSet_EnumType_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FeatureSet_RepeatedFieldEncoding_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FeatureSet_Utf8Validation_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FeatureSet_MessageEncoding_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FeatureSet_JsonFormat_enum_init}, }; static const upb_MiniTableField google_protobuf_FeatureSet__fields[6] = { @@ -1373,9 +1384,9 @@ const upb_MiniTable google__protobuf__FeatureSet_msg_init = { }; static const upb_MiniTableSub google_protobuf_FeatureSetDefaults_submsgs[3] = { - {.submsg = &google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init}, - {.subenum = &google_protobuf_Edition_enum_init}, - {.subenum = &google_protobuf_Edition_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_Edition_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_Edition_enum_init}, }; static const upb_MiniTableField google_protobuf_FeatureSetDefaults__fields[3] = { @@ -1395,8 +1406,8 @@ const upb_MiniTable google__protobuf__FeatureSetDefaults_msg_init = { }; static const upb_MiniTableSub google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_submsgs[2] = { - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.subenum = &google_protobuf_Edition_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_Edition_enum_init}, }; static const upb_MiniTableField google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault__fields[2] = { @@ -1417,7 +1428,7 @@ const upb_MiniTable google__protobuf__FeatureSetDefaults__FeatureSetEditionDefau }; static const upb_MiniTableSub google_protobuf_SourceCodeInfo_submsgs[1] = { - {.submsg = &google__protobuf__SourceCodeInfo__Location_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__SourceCodeInfo__Location_msg_init}, }; static const upb_MiniTableField google_protobuf_SourceCodeInfo__fields[1] = { @@ -1459,7 +1470,7 @@ const upb_MiniTable google__protobuf__SourceCodeInfo__Location_msg_init = { }; static const upb_MiniTableSub google_protobuf_GeneratedCodeInfo_submsgs[1] = { - {.submsg = &google__protobuf__GeneratedCodeInfo__Annotation_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__GeneratedCodeInfo__Annotation_msg_init}, }; static const upb_MiniTableField google_protobuf_GeneratedCodeInfo__fields[1] = { @@ -1477,7 +1488,7 @@ const upb_MiniTable google__protobuf__GeneratedCodeInfo_msg_init = { }; static const upb_MiniTableSub google_protobuf_GeneratedCodeInfo_Annotation_submsgs[1] = { - {.subenum = &google_protobuf_GeneratedCodeInfo_Annotation_Semantic_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_GeneratedCodeInfo_Annotation_Semantic_enum_init}, }; static const upb_MiniTableField google_protobuf_GeneratedCodeInfo_Annotation__fields[5] = { @@ -1541,7 +1552,7 @@ static const upb_MiniTable *messages_layout[32] = { const upb_MiniTableEnum google_protobuf_Edition_enum_init = { 64, - 6, + 7, { 0x7, 0x0, @@ -1551,6 +1562,7 @@ const upb_MiniTableEnum google_protobuf_Edition_enum_init = { 0x1869d, 0x1869e, 0x1869f, + 0x7fffffff, }, }; @@ -1612,7 +1624,7 @@ const upb_MiniTableEnum google_protobuf_FeatureSet_Utf8Validation_enum_init = { 64, 0, { - 0x7, + 0xd, 0x0, }, }; @@ -1736,7 +1748,7 @@ const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout = { * regenerated. */ -static const char descriptor[11620] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', +static const char descriptor[11646] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', '.', 'p', 'r', 'o', 't', 'o', '\022', '\017', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '\"', 'M', '\n', '\021', 'F', 'i', 'l', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'S', 'e', 't', '\022', '8', '\n', '\004', 'f', 'i', 'l', 'e', '\030', '\001', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', @@ -1801,7 +1813,7 @@ static const char descriptor[11620] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', 'g', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\032', '7', '\n', '\r', 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', '\022', '\024', '\n', '\005', 's', 't', 'a', 'r', 't', '\030', '\001', ' ', '\001', '(', '\005', 'R', '\005', 's', 't', 'a', 'r', 't', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', -'\"', '\307', '\004', '\n', '\025', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', 'O', 'p', 't', 'i', 'o', 'n', +'\"', '\314', '\004', '\n', '\025', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', @@ -1811,396 +1823,397 @@ static const char descriptor[11620] = {'\n', ' ', 'g', 'o', 'o', 'g', 'l', 'e', 'n', 's', '.', 'D', 'e', 'c', 'l', 'a', 'r', 'a', 't', 'i', 'o', 'n', 'B', '\003', '\210', '\001', '\002', 'R', '\013', 'd', 'e', 'c', 'l', 'a', 'r', 'a', 't', 'i', 'o', 'n', '\022', '7', '\n', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\030', '2', ' ', '\001', '(', '\013', '2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', -'e', 'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\022', 'h', '\n', '\014', 'v', 'e', 'r', 'i', 'f', 'i', 'c', +'e', 'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\022', 'm', '\n', '\014', 'v', 'e', 'r', 'i', 'f', 'i', 'c', 'a', 't', 'i', 'o', 'n', '\030', '\003', ' ', '\001', '(', '\016', '2', '8', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 'R', 'a', 'n', 'g', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'V', 'e', 'r', 'i', 'f', 'i', 'c', 'a', 't', 'i', 'o', 'n', 'S', 't', 'a', 't', 'e', ':', '\n', 'U', 'N', 'V', 'E', -'R', 'I', 'F', 'I', 'E', 'D', 'R', '\014', 'v', 'e', 'r', 'i', 'f', 'i', 'c', 'a', 't', 'i', 'o', 'n', '\032', '\224', '\001', '\n', '\013', -'D', 'e', 'c', 'l', 'a', 'r', 'a', 't', 'i', 'o', 'n', '\022', '\026', '\n', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\030', '\001', ' ', '\001', -'(', '\005', 'R', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\022', '\033', '\n', '\t', 'f', 'u', 'l', 'l', '_', 'n', 'a', 'm', 'e', '\030', '\002', -' ', '\001', '(', '\t', 'R', '\010', 'f', 'u', 'l', 'l', 'N', 'a', 'm', 'e', '\022', '\022', '\n', '\004', 't', 'y', 'p', 'e', '\030', '\003', ' ', -'\001', '(', '\t', 'R', '\004', 't', 'y', 'p', 'e', '\022', '\032', '\n', '\010', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', '\030', '\005', ' ', '\001', -'(', '\010', 'R', '\010', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', '\022', '\032', '\n', '\010', 'r', 'e', 'p', 'e', 'a', 't', 'e', 'd', '\030', -'\006', ' ', '\001', '(', '\010', 'R', '\010', 'r', 'e', 'p', 'e', 'a', 't', 'e', 'd', 'J', '\004', '\010', '\004', '\020', '\005', '\"', '4', '\n', '\021', -'V', 'e', 'r', 'i', 'f', 'i', 'c', 'a', 't', 'i', 'o', 'n', 'S', 't', 'a', 't', 'e', '\022', '\017', '\n', '\013', 'D', 'E', 'C', 'L', -'A', 'R', 'A', 'T', 'I', 'O', 'N', '\020', '\000', '\022', '\016', '\n', '\n', 'U', 'N', 'V', 'E', 'R', 'I', 'F', 'I', 'E', 'D', '\020', '\001', -'*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\301', '\006', '\n', '\024', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', -'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', -'R', '\004', 'n', 'a', 'm', 'e', '\022', '\026', '\n', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\030', '\003', ' ', '\001', '(', '\005', 'R', '\006', 'n', -'u', 'm', 'b', 'e', 'r', '\022', 'A', '\n', '\005', 'l', 'a', 'b', 'e', 'l', '\030', '\004', ' ', '\001', '(', '\016', '2', '+', '.', 'g', 'o', -'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', -'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'L', 'a', 'b', 'e', 'l', 'R', '\005', 'l', 'a', 'b', 'e', 'l', '\022', '>', '\n', -'\004', 't', 'y', 'p', 'e', '\030', '\005', ' ', '\001', '(', '\016', '2', '*', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', -'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', -'.', 'T', 'y', 'p', 'e', 'R', '\004', 't', 'y', 'p', 'e', '\022', '\033', '\n', '\t', 't', 'y', 'p', 'e', '_', 'n', 'a', 'm', 'e', '\030', -'\006', ' ', '\001', '(', '\t', 'R', '\010', 't', 'y', 'p', 'e', 'N', 'a', 'm', 'e', '\022', '\032', '\n', '\010', 'e', 'x', 't', 'e', 'n', 'd', -'e', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\010', 'e', 'x', 't', 'e', 'n', 'd', 'e', 'e', '\022', '#', '\n', '\r', 'd', 'e', 'f', -'a', 'u', 'l', 't', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\007', ' ', '\001', '(', '\t', 'R', '\014', 'd', 'e', 'f', 'a', 'u', 'l', 't', -'V', 'a', 'l', 'u', 'e', '\022', '\037', '\n', '\013', 'o', 'n', 'e', 'o', 'f', '_', 'i', 'n', 'd', 'e', 'x', '\030', '\t', ' ', '\001', '(', -'\005', 'R', '\n', 'o', 'n', 'e', 'o', 'f', 'I', 'n', 'd', 'e', 'x', '\022', '\033', '\n', '\t', 'j', 's', 'o', 'n', '_', 'n', 'a', 'm', -'e', '\030', '\n', ' ', '\001', '(', '\t', 'R', '\010', 'j', 's', 'o', 'n', 'N', 'a', 'm', 'e', '\022', '7', '\n', '\007', 'o', 'p', 't', 'i', -'o', 'n', 's', '\030', '\010', ' ', '\001', '(', '\013', '2', '\035', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', -'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', -'\'', '\n', '\017', 'p', 'r', 'o', 't', 'o', '3', '_', 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l', '\030', '\021', ' ', '\001', '(', '\010', 'R', -'\016', 'p', 'r', 'o', 't', 'o', '3', 'O', 'p', 't', 'i', 'o', 'n', 'a', 'l', '\"', '\266', '\002', '\n', '\004', 'T', 'y', 'p', 'e', '\022', -'\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'D', 'O', 'U', 'B', 'L', 'E', '\020', '\001', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', -'F', 'L', 'O', 'A', 'T', '\020', '\002', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'I', 'N', 'T', '6', '4', '\020', '\003', '\022', '\017', -'\n', '\013', 'T', 'Y', 'P', 'E', '_', 'U', 'I', 'N', 'T', '6', '4', '\020', '\004', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'I', -'N', 'T', '3', '2', '\020', '\005', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'F', 'I', 'X', 'E', 'D', '6', '4', '\020', '\006', '\022', -'\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'F', 'I', 'X', 'E', 'D', '3', '2', '\020', '\007', '\022', '\r', '\n', '\t', 'T', 'Y', 'P', 'E', -'_', 'B', 'O', 'O', 'L', '\020', '\010', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'S', 'T', 'R', 'I', 'N', 'G', '\020', '\t', '\022', -'\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'G', 'R', 'O', 'U', 'P', '\020', '\n', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'M', -'E', 'S', 'S', 'A', 'G', 'E', '\020', '\013', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'B', 'Y', 'T', 'E', 'S', '\020', '\014', '\022', -'\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'U', 'I', 'N', 'T', '3', '2', '\020', '\r', '\022', '\r', '\n', '\t', 'T', 'Y', 'P', 'E', '_', -'E', 'N', 'U', 'M', '\020', '\016', '\022', '\021', '\n', '\r', 'T', 'Y', 'P', 'E', '_', 'S', 'F', 'I', 'X', 'E', 'D', '3', '2', '\020', '\017', -'\022', '\021', '\n', '\r', 'T', 'Y', 'P', 'E', '_', 'S', 'F', 'I', 'X', 'E', 'D', '6', '4', '\020', '\020', '\022', '\017', '\n', '\013', 'T', 'Y', -'P', 'E', '_', 'S', 'I', 'N', 'T', '3', '2', '\020', '\021', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'S', 'I', 'N', 'T', '6', -'4', '\020', '\022', '\"', 'C', '\n', '\005', 'L', 'a', 'b', 'e', 'l', '\022', '\022', '\n', '\016', 'L', 'A', 'B', 'E', 'L', '_', 'O', 'P', 'T', -'I', 'O', 'N', 'A', 'L', '\020', '\001', '\022', '\022', '\n', '\016', 'L', 'A', 'B', 'E', 'L', '_', 'R', 'E', 'P', 'E', 'A', 'T', 'E', 'D', -'\020', '\003', '\022', '\022', '\n', '\016', 'L', 'A', 'B', 'E', 'L', '_', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D', '\020', '\002', '\"', 'c', '\n', -'\024', 'O', 'n', 'e', 'o', 'f', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', -'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '7', '\n', '\007', 'o', 'p', 't', 'i', 'o', -'n', 's', '\030', '\002', ' ', '\001', '(', '\013', '2', '\035', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', -'f', '.', 'O', 'n', 'e', 'o', 'f', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\"', '\343', -'\002', '\n', '\023', 'E', 'n', 'u', 'm', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', -'\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '?', '\n', '\005', 'v', 'a', 'l', 'u', -'e', '\030', '\002', ' ', '\003', '(', '\013', '2', ')', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', -'.', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', -'R', '\005', 'v', 'a', 'l', 'u', 'e', '\022', '6', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', -'\034', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'O', 'p', 't', -'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', ']', '\n', '\016', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', -'_', 'r', 'a', 'n', 'g', 'e', '\030', '\004', ' ', '\003', '(', '\013', '2', '6', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', -'t', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', -'.', 'E', 'n', 'u', 'm', 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', 'R', '\r', 'r', 'e', 's', 'e', 'r', -'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', '\022', '#', '\n', '\r', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', '_', 'n', 'a', 'm', 'e', -'\030', '\005', ' ', '\003', '(', '\t', 'R', '\014', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'N', 'a', 'm', 'e', '\032', ';', '\n', '\021', 'E', -'n', 'u', 'm', 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', '\022', '\024', '\n', '\005', 's', 't', 'a', 'r', 't', -'\030', '\001', ' ', '\001', '(', '\005', 'R', '\005', 's', 't', 'a', 'r', 't', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\002', ' ', '\001', '(', -'\005', 'R', '\003', 'e', 'n', 'd', '\"', '\203', '\001', '\n', '\030', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'D', 'e', 's', 'c', 'r', -'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', -'\004', 'n', 'a', 'm', 'e', '\022', '\026', '\n', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\030', '\002', ' ', '\001', '(', '\005', 'R', '\006', 'n', 'u', -'m', 'b', 'e', 'r', '\022', ';', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '!', '.', 'g', -'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'O', -'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\"', '\247', '\001', '\n', '\026', 'S', 'e', 'r', 'v', 'i', -'c', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', -'\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '>', '\n', '\006', 'm', 'e', 't', 'h', 'o', 'd', '\030', '\002', ' ', -'\003', '(', '\013', '2', '&', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', -'h', 'o', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\006', 'm', 'e', 't', 'h', 'o', -'d', '\022', '9', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '\037', '.', 'g', 'o', 'o', 'g', -'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'O', 'p', 't', 'i', 'o', 'n', -'s', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\"', '\211', '\002', '\n', '\025', 'M', 'e', 't', 'h', 'o', 'd', 'D', 'e', 's', 'c', -'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', -'R', '\004', 'n', 'a', 'm', 'e', '\022', '\035', '\n', '\n', 'i', 'n', 'p', 'u', 't', '_', 't', 'y', 'p', 'e', '\030', '\002', ' ', '\001', '(', -'\t', 'R', '\t', 'i', 'n', 'p', 'u', 't', 'T', 'y', 'p', 'e', '\022', '\037', '\n', '\013', 'o', 'u', 't', 'p', 'u', 't', '_', 't', 'y', -'p', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\n', 'o', 'u', 't', 'p', 'u', 't', 'T', 'y', 'p', 'e', '\022', '8', '\n', '\007', 'o', -'p', 't', 'i', 'o', 'n', 's', '\030', '\004', ' ', '\001', '(', '\013', '2', '\036', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', -'t', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', 'h', 'o', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', -'o', 'n', 's', '\022', '0', '\n', '\020', 'c', 'l', 'i', 'e', 'n', 't', '_', 's', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\030', '\005', -' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\017', 'c', 'l', 'i', 'e', 'n', 't', 'S', 't', 'r', 'e', 'a', 'm', -'i', 'n', 'g', '\022', '0', '\n', '\020', 's', 'e', 'r', 'v', 'e', 'r', '_', 's', 't', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\030', '\006', -' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\017', 's', 'e', 'r', 'v', 'e', 'r', 'S', 't', 'r', 'e', 'a', 'm', -'i', 'n', 'g', '\"', '\312', '\t', '\n', '\013', 'F', 'i', 'l', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '!', '\n', '\014', 'j', 'a', -'v', 'a', '_', 'p', 'a', 'c', 'k', 'a', 'g', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\013', 'j', 'a', 'v', 'a', 'P', 'a', 'c', -'k', 'a', 'g', 'e', '\022', '0', '\n', '\024', 'j', 'a', 'v', 'a', '_', 'o', 'u', 't', 'e', 'r', '_', 'c', 'l', 'a', 's', 's', 'n', -'a', 'm', 'e', '\030', '\010', ' ', '\001', '(', '\t', 'R', '\022', 'j', 'a', 'v', 'a', 'O', 'u', 't', 'e', 'r', 'C', 'l', 'a', 's', 's', -'n', 'a', 'm', 'e', '\022', '5', '\n', '\023', 'j', 'a', 'v', 'a', '_', 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', '_', 'f', 'i', 'l', -'e', 's', '\030', '\n', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\021', 'j', 'a', 'v', 'a', 'M', 'u', 'l', 't', -'i', 'p', 'l', 'e', 'F', 'i', 'l', 'e', 's', '\022', 'D', '\n', '\035', 'j', 'a', 'v', 'a', '_', 'g', 'e', 'n', 'e', 'r', 'a', 't', -'e', '_', 'e', 'q', 'u', 'a', 'l', 's', '_', 'a', 'n', 'd', '_', 'h', 'a', 's', 'h', '\030', '\024', ' ', '\001', '(', '\010', 'B', '\002', -'\030', '\001', 'R', '\031', 'j', 'a', 'v', 'a', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'E', 'q', 'u', 'a', 'l', 's', 'A', 'n', 'd', -'H', 'a', 's', 'h', '\022', ':', '\n', '\026', 'j', 'a', 'v', 'a', '_', 's', 't', 'r', 'i', 'n', 'g', '_', 'c', 'h', 'e', 'c', 'k', -'_', 'u', 't', 'f', '8', '\030', '\033', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\023', 'j', 'a', 'v', 'a', 'S', -'t', 'r', 'i', 'n', 'g', 'C', 'h', 'e', 'c', 'k', 'U', 't', 'f', '8', '\022', 'S', '\n', '\014', 'o', 'p', 't', 'i', 'm', 'i', 'z', -'e', '_', 'f', 'o', 'r', '\030', '\t', ' ', '\001', '(', '\016', '2', ')', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', -'o', 'b', 'u', 'f', '.', 'F', 'i', 'l', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'O', 'p', 't', 'i', 'm', 'i', 'z', 'e', -'M', 'o', 'd', 'e', ':', '\005', 'S', 'P', 'E', 'E', 'D', 'R', '\013', 'o', 'p', 't', 'i', 'm', 'i', 'z', 'e', 'F', 'o', 'r', '\022', -'\035', '\n', '\n', 'g', 'o', '_', 'p', 'a', 'c', 'k', 'a', 'g', 'e', '\030', '\013', ' ', '\001', '(', '\t', 'R', '\t', 'g', 'o', 'P', 'a', -'c', 'k', 'a', 'g', 'e', '\022', '5', '\n', '\023', 'c', 'c', '_', 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', -'c', 'e', 's', '\030', '\020', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\021', 'c', 'c', 'G', 'e', 'n', 'e', 'r', -'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '9', '\n', '\025', 'j', 'a', 'v', 'a', '_', 'g', 'e', 'n', 'e', 'r', 'i', -'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '\021', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\023', -'j', 'a', 'v', 'a', 'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '5', '\n', '\023', 'p', 'y', -'_', 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '\022', ' ', '\001', '(', '\010', ':', '\005', -'f', 'a', 'l', 's', 'e', 'R', '\021', 'p', 'y', 'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', -'7', '\n', '\024', 'p', 'h', 'p', '_', 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '*', -' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\022', 'p', 'h', 'p', 'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S', 'e', -'r', 'v', 'i', 'c', 'e', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\027', ' ', '\001', '(', -'\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', '.', '\n', '\020', 'c', -'c', '_', 'e', 'n', 'a', 'b', 'l', 'e', '_', 'a', 'r', 'e', 'n', 'a', 's', '\030', '\037', ' ', '\001', '(', '\010', ':', '\004', 't', 'r', -'u', 'e', 'R', '\016', 'c', 'c', 'E', 'n', 'a', 'b', 'l', 'e', 'A', 'r', 'e', 'n', 'a', 's', '\022', '*', '\n', '\021', 'o', 'b', 'j', -'c', '_', 'c', 'l', 'a', 's', 's', '_', 'p', 'r', 'e', 'f', 'i', 'x', '\030', '$', ' ', '\001', '(', '\t', 'R', '\017', 'o', 'b', 'j', -'c', 'C', 'l', 'a', 's', 's', 'P', 'r', 'e', 'f', 'i', 'x', '\022', ')', '\n', '\020', 'c', 's', 'h', 'a', 'r', 'p', '_', 'n', 'a', -'m', 'e', 's', 'p', 'a', 'c', 'e', '\030', '%', ' ', '\001', '(', '\t', 'R', '\017', 'c', 's', 'h', 'a', 'r', 'p', 'N', 'a', 'm', 'e', -'s', 'p', 'a', 'c', 'e', '\022', '!', '\n', '\014', 's', 'w', 'i', 'f', 't', '_', 'p', 'r', 'e', 'f', 'i', 'x', '\030', '\'', ' ', '\001', -'(', '\t', 'R', '\013', 's', 'w', 'i', 'f', 't', 'P', 'r', 'e', 'f', 'i', 'x', '\022', '(', '\n', '\020', 'p', 'h', 'p', '_', 'c', 'l', -'a', 's', 's', '_', 'p', 'r', 'e', 'f', 'i', 'x', '\030', '(', ' ', '\001', '(', '\t', 'R', '\016', 'p', 'h', 'p', 'C', 'l', 'a', 's', -'s', 'P', 'r', 'e', 'f', 'i', 'x', '\022', '#', '\n', '\r', 'p', 'h', 'p', '_', 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\030', -')', ' ', '\001', '(', '\t', 'R', '\014', 'p', 'h', 'p', 'N', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\022', '4', '\n', '\026', 'p', 'h', -'p', '_', 'm', 'e', 't', 'a', 'd', 'a', 't', 'a', '_', 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\030', ',', ' ', '\001', '(', -'\t', 'R', '\024', 'p', 'h', 'p', 'M', 'e', 't', 'a', 'd', 'a', 't', 'a', 'N', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\022', '!', -'\n', '\014', 'r', 'u', 'b', 'y', '_', 'p', 'a', 'c', 'k', 'a', 'g', 'e', '\030', '-', ' ', '\001', '(', '\t', 'R', '\013', 'r', 'u', 'b', -'y', 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\022', '7', '\n', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\030', '2', ' ', '\001', '(', -'\013', '2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', -'r', 'e', 'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', -'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', -'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', -'t', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', -'p', 't', 'i', 'o', 'n', '\"', ':', '\n', '\014', 'O', 'p', 't', 'i', 'm', 'i', 'z', 'e', 'M', 'o', 'd', 'e', '\022', '\t', '\n', '\005', -'S', 'P', 'E', 'E', 'D', '\020', '\001', '\022', '\r', '\n', '\t', 'C', 'O', 'D', 'E', '_', 'S', 'I', 'Z', 'E', '\020', '\002', '\022', '\020', '\n', -'\014', 'L', 'I', 'T', 'E', '_', 'R', 'U', 'N', 'T', 'I', 'M', 'E', '\020', '\003', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', -'\002', 'J', '\004', '\010', '&', '\020', '\'', '\"', '\364', '\003', '\n', '\016', 'M', 'e', 's', 's', 'a', 'g', 'e', 'O', 'p', 't', 'i', 'o', 'n', -'s', '\022', '<', '\n', '\027', 'm', 'e', 's', 's', 'a', 'g', 'e', '_', 's', 'e', 't', '_', 'w', 'i', 'r', 'e', '_', 'f', 'o', 'r', -'m', 'a', 't', '\030', '\001', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\024', 'm', 'e', 's', 's', 'a', 'g', 'e', -'S', 'e', 't', 'W', 'i', 'r', 'e', 'F', 'o', 'r', 'm', 'a', 't', '\022', 'L', '\n', '\037', 'n', 'o', '_', 's', 't', 'a', 'n', 'd', -'a', 'r', 'd', '_', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', '_', 'a', 'c', 'c', 'e', 's', 's', 'o', 'r', '\030', '\002', -' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\034', 'n', 'o', 'S', 't', 'a', 'n', 'd', 'a', 'r', 'd', 'D', 'e', -'s', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'A', 'c', 'c', 'e', 's', 's', 'o', 'r', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', -'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', -'c', 'a', 't', 'e', 'd', '\022', '\033', '\n', '\t', 'm', 'a', 'p', '_', 'e', 'n', 't', 'r', 'y', '\030', '\007', ' ', '\001', '(', '\010', 'R', -'\010', 'm', 'a', 'p', 'E', 'n', 't', 'r', 'y', '\022', 'V', '\n', '&', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '_', 'l', -'e', 'g', 'a', 'c', 'y', '_', 'j', 's', 'o', 'n', '_', 'f', 'i', 'e', 'l', 'd', '_', 'c', 'o', 'n', 'f', 'l', 'i', 'c', 't', -'s', '\030', '\013', ' ', '\001', '(', '\010', 'B', '\002', '\030', '\001', 'R', '\"', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', 'L', 'e', -'g', 'a', 'c', 'y', 'J', 's', 'o', 'n', 'F', 'i', 'e', 'l', 'd', 'C', 'o', 'n', 'f', 'l', 'i', 'c', 't', 's', '\022', '7', '\n', -'\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\030', '\014', ' ', '\001', '(', '\013', '2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', -'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', -'u', 'r', 'e', 's', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', -'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', -'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', -'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', -'\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\004', '\020', '\005', 'J', '\004', '\010', '\005', '\020', '\006', 'J', '\004', '\010', '\006', '\020', '\007', 'J', '\004', -'\010', '\010', '\020', '\t', 'J', '\004', '\010', '\t', '\020', '\n', '\"', '\255', '\n', '\n', '\014', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', -'n', 's', '\022', 'A', '\n', '\005', 'c', 't', 'y', 'p', 'e', '\030', '\001', ' ', '\001', '(', '\016', '2', '#', '.', 'g', 'o', 'o', 'g', 'l', -'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'C', -'T', 'y', 'p', 'e', ':', '\006', 'S', 'T', 'R', 'I', 'N', 'G', 'R', '\005', 'c', 't', 'y', 'p', 'e', '\022', '\026', '\n', '\006', 'p', 'a', -'c', 'k', 'e', 'd', '\030', '\002', ' ', '\001', '(', '\010', 'R', '\006', 'p', 'a', 'c', 'k', 'e', 'd', '\022', 'G', '\n', '\006', 'j', 's', 't', -'y', 'p', 'e', '\030', '\006', ' ', '\001', '(', '\016', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', -'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'J', 'S', 'T', 'y', 'p', 'e', ':', '\t', 'J', -'S', '_', 'N', 'O', 'R', 'M', 'A', 'L', 'R', '\006', 'j', 's', 't', 'y', 'p', 'e', '\022', '\031', '\n', '\004', 'l', 'a', 'z', 'y', '\030', -'\005', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\004', 'l', 'a', 'z', 'y', '\022', '.', '\n', '\017', 'u', 'n', 'v', -'e', 'r', 'i', 'f', 'i', 'e', 'd', '_', 'l', 'a', 'z', 'y', '\030', '\017', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', -'R', '\016', 'u', 'n', 'v', 'e', 'r', 'i', 'f', 'i', 'e', 'd', 'L', 'a', 'z', 'y', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', -'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', -'c', 'a', 't', 'e', 'd', '\022', '\031', '\n', '\004', 'w', 'e', 'a', 'k', '\030', '\n', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', -'e', 'R', '\004', 'w', 'e', 'a', 'k', '\022', '(', '\n', '\014', 'd', 'e', 'b', 'u', 'g', '_', 'r', 'e', 'd', 'a', 'c', 't', '\030', '\020', -' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\013', 'd', 'e', 'b', 'u', 'g', 'R', 'e', 'd', 'a', 'c', 't', '\022', -'K', '\n', '\t', 'r', 'e', 't', 'e', 'n', 't', 'i', 'o', 'n', '\030', '\021', ' ', '\001', '(', '\016', '2', '-', '.', 'g', 'o', 'o', 'g', -'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', -'O', 'p', 't', 'i', 'o', 'n', 'R', 'e', 't', 'e', 'n', 't', 'i', 'o', 'n', 'R', '\t', 'r', 'e', 't', 'e', 'n', 't', 'i', 'o', -'n', '\022', 'H', '\n', '\007', 't', 'a', 'r', 'g', 'e', 't', 's', '\030', '\023', ' ', '\003', '(', '\016', '2', '.', '.', 'g', 'o', 'o', 'g', -'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', -'O', 'p', 't', 'i', 'o', 'n', 'T', 'a', 'r', 'g', 'e', 't', 'T', 'y', 'p', 'e', 'R', '\007', 't', 'a', 'r', 'g', 'e', 't', 's', -'\022', 'W', '\n', '\020', 'e', 'd', 'i', 't', 'i', 'o', 'n', '_', 'd', 'e', 'f', 'a', 'u', 'l', 't', 's', '\030', '\024', ' ', '\003', '(', -'\013', '2', ',', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', -'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'E', 'd', 'i', 't', 'i', 'o', 'n', 'D', 'e', 'f', 'a', 'u', 'l', 't', 'R', '\017', 'e', -'d', 'i', 't', 'i', 'o', 'n', 'D', 'e', 'f', 'a', 'u', 'l', 't', 's', '\022', '7', '\n', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', -'s', '\030', '\025', ' ', '\001', '(', '\013', '2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', -'.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\022', 'X', '\n', '\024', -'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', -'(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', -'t', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', -'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\032', 'Z', '\n', '\016', 'E', 'd', 'i', 't', 'i', 'o', 'n', 'D', 'e', 'f', -'a', 'u', 'l', 't', '\022', '2', '\n', '\007', 'e', 'd', 'i', 't', 'i', 'o', 'n', '\030', '\003', ' ', '\001', '(', '\016', '2', '\030', '.', 'g', -'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'd', 'i', 't', 'i', 'o', 'n', 'R', '\007', 'e', -'d', 'i', 't', 'i', 'o', 'n', '\022', '\024', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\005', 'v', 'a', -'l', 'u', 'e', '\"', '/', '\n', '\005', 'C', 'T', 'y', 'p', 'e', '\022', '\n', '\n', '\006', 'S', 'T', 'R', 'I', 'N', 'G', '\020', '\000', '\022', -'\010', '\n', '\004', 'C', 'O', 'R', 'D', '\020', '\001', '\022', '\020', '\n', '\014', 'S', 'T', 'R', 'I', 'N', 'G', '_', 'P', 'I', 'E', 'C', 'E', -'\020', '\002', '\"', '5', '\n', '\006', 'J', 'S', 'T', 'y', 'p', 'e', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'N', 'O', 'R', 'M', 'A', 'L', -'\020', '\000', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'S', 'T', 'R', 'I', 'N', 'G', '\020', '\001', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'N', -'U', 'M', 'B', 'E', 'R', '\020', '\002', '\"', 'U', '\n', '\017', 'O', 'p', 't', 'i', 'o', 'n', 'R', 'e', 't', 'e', 'n', 't', 'i', 'o', -'n', '\022', '\025', '\n', '\021', 'R', 'E', 'T', 'E', 'N', 'T', 'I', 'O', 'N', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', -'\025', '\n', '\021', 'R', 'E', 'T', 'E', 'N', 'T', 'I', 'O', 'N', '_', 'R', 'U', 'N', 'T', 'I', 'M', 'E', '\020', '\001', '\022', '\024', '\n', -'\020', 'R', 'E', 'T', 'E', 'N', 'T', 'I', 'O', 'N', '_', 'S', 'O', 'U', 'R', 'C', 'E', '\020', '\002', '\"', '\214', '\002', '\n', '\020', 'O', -'p', 't', 'i', 'o', 'n', 'T', 'a', 'r', 'g', 'e', 't', 'T', 'y', 'p', 'e', '\022', '\027', '\n', '\023', 'T', 'A', 'R', 'G', 'E', 'T', -'_', 'T', 'Y', 'P', 'E', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\024', '\n', '\020', 'T', 'A', 'R', 'G', 'E', 'T', -'_', 'T', 'Y', 'P', 'E', '_', 'F', 'I', 'L', 'E', '\020', '\001', '\022', '\037', '\n', '\033', 'T', 'A', 'R', 'G', 'E', 'T', '_', 'T', 'Y', -'P', 'E', '_', 'E', 'X', 'T', 'E', 'N', 'S', 'I', 'O', 'N', '_', 'R', 'A', 'N', 'G', 'E', '\020', '\002', '\022', '\027', '\n', '\023', 'T', -'A', 'R', 'G', 'E', 'T', '_', 'T', 'Y', 'P', 'E', '_', 'M', 'E', 'S', 'S', 'A', 'G', 'E', '\020', '\003', '\022', '\025', '\n', '\021', 'T', -'A', 'R', 'G', 'E', 'T', '_', 'T', 'Y', 'P', 'E', '_', 'F', 'I', 'E', 'L', 'D', '\020', '\004', '\022', '\025', '\n', '\021', 'T', 'A', 'R', -'G', 'E', 'T', '_', 'T', 'Y', 'P', 'E', '_', 'O', 'N', 'E', 'O', 'F', '\020', '\005', '\022', '\024', '\n', '\020', 'T', 'A', 'R', 'G', 'E', -'T', '_', 'T', 'Y', 'P', 'E', '_', 'E', 'N', 'U', 'M', '\020', '\006', '\022', '\032', '\n', '\026', 'T', 'A', 'R', 'G', 'E', 'T', '_', 'T', -'Y', 'P', 'E', '_', 'E', 'N', 'U', 'M', '_', 'E', 'N', 'T', 'R', 'Y', '\020', '\007', '\022', '\027', '\n', '\023', 'T', 'A', 'R', 'G', 'E', -'T', '_', 'T', 'Y', 'P', 'E', '_', 'S', 'E', 'R', 'V', 'I', 'C', 'E', '\020', '\010', '\022', '\026', '\n', '\022', 'T', 'A', 'R', 'G', 'E', -'T', '_', 'T', 'Y', 'P', 'E', '_', 'M', 'E', 'T', 'H', 'O', 'D', '\020', '\t', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', -'\002', 'J', '\004', '\010', '\004', '\020', '\005', 'J', '\004', '\010', '\022', '\020', '\023', '\"', '\254', '\001', '\n', '\014', 'O', 'n', 'e', 'o', 'f', 'O', 'p', -'t', 'i', 'o', 'n', 's', '\022', '7', '\n', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\030', '\001', ' ', '\001', '(', '\013', '2', '\033', -'.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', -'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', -'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', -'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', -'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', -'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\321', '\002', '\n', '\013', 'E', 'n', 'u', 'm', 'O', 'p', 't', -'i', 'o', 'n', 's', '\022', '\037', '\n', '\013', 'a', 'l', 'l', 'o', 'w', '_', 'a', 'l', 'i', 'a', 's', '\030', '\002', ' ', '\001', '(', '\010', -'R', '\n', 'a', 'l', 'l', 'o', 'w', 'A', 'l', 'i', 'a', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', -'d', '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', -'d', '\022', 'V', '\n', '&', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '_', 'l', 'e', 'g', 'a', 'c', 'y', '_', 'j', 's', -'o', 'n', '_', 'f', 'i', 'e', 'l', 'd', '_', 'c', 'o', 'n', 'f', 'l', 'i', 'c', 't', 's', '\030', '\006', ' ', '\001', '(', '\010', 'B', -'\002', '\030', '\001', 'R', '\"', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', 'L', 'e', 'g', 'a', 'c', 'y', 'J', 's', 'o', 'n', -'F', 'i', 'e', 'l', 'd', 'C', 'o', 'n', 'f', 'l', 'i', 'c', 't', 's', '\022', '7', '\n', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', -'s', '\030', '\007', ' ', '\001', '(', '\013', '2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', -'.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\022', 'X', '\n', '\024', -'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', -'(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', -'t', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', -'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', -'\005', '\020', '\006', '\"', '\201', '\002', '\n', '\020', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', -'%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\001', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', -'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', '7', '\n', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', -'\030', '\002', ' ', '\001', '(', '\013', '2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', -'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\022', '(', '\n', '\014', 'd', -'e', 'b', 'u', 'g', '_', 'r', 'e', 'd', 'a', 'c', 't', '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', -'\013', 'd', 'e', 'b', 'u', 'g', 'R', 'e', 'd', 'a', 'c', 't', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', -'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', -'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', -'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', -'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\325', '\001', '\n', '\016', 'S', 'e', 'r', 'v', 'i', 'c', 'e', -'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '7', '\n', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\030', '\"', ' ', '\001', '(', '\013', -'2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', -'e', 'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', -'t', 'e', 'd', '\030', '!', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', -'t', 'e', 'd', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', -'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', -'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', -'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', -'\200', '\200', '\200', '\002', '\"', '\231', '\003', '\n', '\r', 'M', 'e', 't', 'h', 'o', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '%', '\n', -'\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '!', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', -'\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'q', '\n', '\021', 'i', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', -'y', '_', 'l', 'e', 'v', 'e', 'l', '\030', '\"', ' ', '\001', '(', '\016', '2', '/', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', -'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', 'h', 'o', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'I', 'd', 'e', 'm', -'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', 'v', 'e', 'l', ':', '\023', 'I', 'D', 'E', 'M', 'P', 'O', 'T', 'E', 'N', 'C', 'Y', -'_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', 'R', '\020', 'i', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', 'v', 'e', -'l', '\022', '7', '\n', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\030', '#', ' ', '\001', '(', '\013', '2', '\033', '.', 'g', 'o', 'o', -'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'R', '\010', -'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', +'R', 'I', 'F', 'I', 'E', 'D', 'B', '\003', '\210', '\001', '\002', 'R', '\014', 'v', 'e', 'r', 'i', 'f', 'i', 'c', 'a', 't', 'i', 'o', 'n', +'\032', '\224', '\001', '\n', '\013', 'D', 'e', 'c', 'l', 'a', 'r', 'a', 't', 'i', 'o', 'n', '\022', '\026', '\n', '\006', 'n', 'u', 'm', 'b', 'e', +'r', '\030', '\001', ' ', '\001', '(', '\005', 'R', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\022', '\033', '\n', '\t', 'f', 'u', 'l', 'l', '_', 'n', +'a', 'm', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\010', 'f', 'u', 'l', 'l', 'N', 'a', 'm', 'e', '\022', '\022', '\n', '\004', 't', 'y', +'p', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\004', 't', 'y', 'p', 'e', '\022', '\032', '\n', '\010', 'r', 'e', 's', 'e', 'r', 'v', 'e', +'d', '\030', '\005', ' ', '\001', '(', '\010', 'R', '\010', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', '\022', '\032', '\n', '\010', 'r', 'e', 'p', 'e', +'a', 't', 'e', 'd', '\030', '\006', ' ', '\001', '(', '\010', 'R', '\010', 'r', 'e', 'p', 'e', 'a', 't', 'e', 'd', 'J', '\004', '\010', '\004', '\020', +'\005', '\"', '4', '\n', '\021', 'V', 'e', 'r', 'i', 'f', 'i', 'c', 'a', 't', 'i', 'o', 'n', 'S', 't', 'a', 't', 'e', '\022', '\017', '\n', +'\013', 'D', 'E', 'C', 'L', 'A', 'R', 'A', 'T', 'I', 'O', 'N', '\020', '\000', '\022', '\016', '\n', '\n', 'U', 'N', 'V', 'E', 'R', 'I', 'F', +'I', 'E', 'D', '\020', '\001', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\301', '\006', '\n', '\024', 'F', 'i', 'e', 'l', +'d', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', +'\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '\026', '\n', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\030', '\003', ' ', '\001', +'(', '\005', 'R', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\022', 'A', '\n', '\005', 'l', 'a', 'b', 'e', 'l', '\030', '\004', ' ', '\001', '(', '\016', +'2', '+', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', +'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '.', 'L', 'a', 'b', 'e', 'l', 'R', '\005', 'l', 'a', 'b', +'e', 'l', '\022', '>', '\n', '\004', 't', 'y', 'p', 'e', '\030', '\005', ' ', '\001', '(', '\016', '2', '*', '.', 'g', 'o', 'o', 'g', 'l', 'e', +'.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', +'P', 'r', 'o', 't', 'o', '.', 'T', 'y', 'p', 'e', 'R', '\004', 't', 'y', 'p', 'e', '\022', '\033', '\n', '\t', 't', 'y', 'p', 'e', '_', +'n', 'a', 'm', 'e', '\030', '\006', ' ', '\001', '(', '\t', 'R', '\010', 't', 'y', 'p', 'e', 'N', 'a', 'm', 'e', '\022', '\032', '\n', '\010', 'e', +'x', 't', 'e', 'n', 'd', 'e', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\010', 'e', 'x', 't', 'e', 'n', 'd', 'e', 'e', '\022', '#', +'\n', '\r', 'd', 'e', 'f', 'a', 'u', 'l', 't', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\007', ' ', '\001', '(', '\t', 'R', '\014', 'd', 'e', +'f', 'a', 'u', 'l', 't', 'V', 'a', 'l', 'u', 'e', '\022', '\037', '\n', '\013', 'o', 'n', 'e', 'o', 'f', '_', 'i', 'n', 'd', 'e', 'x', +'\030', '\t', ' ', '\001', '(', '\005', 'R', '\n', 'o', 'n', 'e', 'o', 'f', 'I', 'n', 'd', 'e', 'x', '\022', '\033', '\n', '\t', 'j', 's', 'o', +'n', '_', 'n', 'a', 'm', 'e', '\030', '\n', ' ', '\001', '(', '\t', 'R', '\010', 'j', 's', 'o', 'n', 'N', 'a', 'm', 'e', '\022', '7', '\n', +'\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\010', ' ', '\001', '(', '\013', '2', '\035', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', +'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', +'i', 'o', 'n', 's', '\022', '\'', '\n', '\017', 'p', 'r', 'o', 't', 'o', '3', '_', 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l', '\030', '\021', +' ', '\001', '(', '\010', 'R', '\016', 'p', 'r', 'o', 't', 'o', '3', 'O', 'p', 't', 'i', 'o', 'n', 'a', 'l', '\"', '\266', '\002', '\n', '\004', +'T', 'y', 'p', 'e', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'D', 'O', 'U', 'B', 'L', 'E', '\020', '\001', '\022', '\016', '\n', '\n', +'T', 'Y', 'P', 'E', '_', 'F', 'L', 'O', 'A', 'T', '\020', '\002', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'I', 'N', 'T', '6', +'4', '\020', '\003', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'U', 'I', 'N', 'T', '6', '4', '\020', '\004', '\022', '\016', '\n', '\n', 'T', +'Y', 'P', 'E', '_', 'I', 'N', 'T', '3', '2', '\020', '\005', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'F', 'I', 'X', 'E', 'D', +'6', '4', '\020', '\006', '\022', '\020', '\n', '\014', 'T', 'Y', 'P', 'E', '_', 'F', 'I', 'X', 'E', 'D', '3', '2', '\020', '\007', '\022', '\r', '\n', +'\t', 'T', 'Y', 'P', 'E', '_', 'B', 'O', 'O', 'L', '\020', '\010', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'S', 'T', 'R', 'I', +'N', 'G', '\020', '\t', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'G', 'R', 'O', 'U', 'P', '\020', '\n', '\022', '\020', '\n', '\014', 'T', +'Y', 'P', 'E', '_', 'M', 'E', 'S', 'S', 'A', 'G', 'E', '\020', '\013', '\022', '\016', '\n', '\n', 'T', 'Y', 'P', 'E', '_', 'B', 'Y', 'T', +'E', 'S', '\020', '\014', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'U', 'I', 'N', 'T', '3', '2', '\020', '\r', '\022', '\r', '\n', '\t', +'T', 'Y', 'P', 'E', '_', 'E', 'N', 'U', 'M', '\020', '\016', '\022', '\021', '\n', '\r', 'T', 'Y', 'P', 'E', '_', 'S', 'F', 'I', 'X', 'E', +'D', '3', '2', '\020', '\017', '\022', '\021', '\n', '\r', 'T', 'Y', 'P', 'E', '_', 'S', 'F', 'I', 'X', 'E', 'D', '6', '4', '\020', '\020', '\022', +'\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', 'S', 'I', 'N', 'T', '3', '2', '\020', '\021', '\022', '\017', '\n', '\013', 'T', 'Y', 'P', 'E', '_', +'S', 'I', 'N', 'T', '6', '4', '\020', '\022', '\"', 'C', '\n', '\005', 'L', 'a', 'b', 'e', 'l', '\022', '\022', '\n', '\016', 'L', 'A', 'B', 'E', +'L', '_', 'O', 'P', 'T', 'I', 'O', 'N', 'A', 'L', '\020', '\001', '\022', '\022', '\n', '\016', 'L', 'A', 'B', 'E', 'L', '_', 'R', 'E', 'P', +'E', 'A', 'T', 'E', 'D', '\020', '\003', '\022', '\022', '\n', '\016', 'L', 'A', 'B', 'E', 'L', '_', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D', +'\020', '\002', '\"', 'c', '\n', '\024', 'O', 'n', 'e', 'o', 'f', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', +'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '7', '\n', '\007', +'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\002', ' ', '\001', '(', '\013', '2', '\035', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', +'o', 't', 'o', 'b', 'u', 'f', '.', 'O', 'n', 'e', 'o', 'f', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', +'o', 'n', 's', '\"', '\343', '\002', '\n', '\023', 'E', 'n', 'u', 'm', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', +'t', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '?', '\n', +'\005', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\003', '(', '\013', '2', ')', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', +'t', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', +'P', 'r', 'o', 't', 'o', 'R', '\005', 'v', 'a', 'l', 'u', 'e', '\022', '6', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', +' ', '\001', '(', '\013', '2', '\034', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', +'u', 'm', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', ']', '\n', '\016', 'r', 'e', 's', +'e', 'r', 'v', 'e', 'd', '_', 'r', 'a', 'n', 'g', 'e', '\030', '\004', ' ', '\003', '(', '\013', '2', '6', '.', 'g', 'o', 'o', 'g', 'l', +'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', +'P', 'r', 'o', 't', 'o', '.', 'E', 'n', 'u', 'm', 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', 'R', '\r', +'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', '\022', '#', '\n', '\r', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', +'_', 'n', 'a', 'm', 'e', '\030', '\005', ' ', '\003', '(', '\t', 'R', '\014', 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'N', 'a', 'm', 'e', +'\032', ';', '\n', '\021', 'E', 'n', 'u', 'm', 'R', 'e', 's', 'e', 'r', 'v', 'e', 'd', 'R', 'a', 'n', 'g', 'e', '\022', '\024', '\n', '\005', +'s', 't', 'a', 'r', 't', '\030', '\001', ' ', '\001', '(', '\005', 'R', '\005', 's', 't', 'a', 'r', 't', '\022', '\020', '\n', '\003', 'e', 'n', 'd', +'\030', '\002', ' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', '\"', '\203', '\001', '\n', '\030', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', +'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\001', +' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '\026', '\n', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\030', '\002', ' ', '\001', '(', +'\005', 'R', '\006', 'n', 'u', 'm', 'b', 'e', 'r', '\022', ';', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', +'\013', '2', '!', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'n', 'u', 'm', 'V', +'a', 'l', 'u', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\"', '\247', '\001', '\n', '\026', +'S', 'e', 'r', 'v', 'i', 'c', 'e', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', +'\004', 'n', 'a', 'm', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '>', '\n', '\006', 'm', 'e', 't', 'h', +'o', 'd', '\030', '\002', ' ', '\003', '(', '\013', '2', '&', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', +'f', '.', 'M', 'e', 't', 'h', 'o', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', 'R', '\006', +'m', 'e', 't', 'h', 'o', 'd', '\022', '9', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '\037', +'.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'O', +'p', 't', 'i', 'o', 'n', 's', 'R', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\"', '\211', '\002', '\n', '\025', 'M', 'e', 't', 'h', 'o', +'d', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'P', 'r', 'o', 't', 'o', '\022', '\022', '\n', '\004', 'n', 'a', 'm', 'e', '\030', +'\001', ' ', '\001', '(', '\t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', '\035', '\n', '\n', 'i', 'n', 'p', 'u', 't', '_', 't', 'y', 'p', 'e', +'\030', '\002', ' ', '\001', '(', '\t', 'R', '\t', 'i', 'n', 'p', 'u', 't', 'T', 'y', 'p', 'e', '\022', '\037', '\n', '\013', 'o', 'u', 't', 'p', +'u', 't', '_', 't', 'y', 'p', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\n', 'o', 'u', 't', 'p', 'u', 't', 'T', 'y', 'p', 'e', +'\022', '8', '\n', '\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\030', '\004', ' ', '\001', '(', '\013', '2', '\036', '.', 'g', 'o', 'o', 'g', 'l', +'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', 'h', 'o', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', 'R', +'\007', 'o', 'p', 't', 'i', 'o', 'n', 's', '\022', '0', '\n', '\020', 'c', 'l', 'i', 'e', 'n', 't', '_', 's', 't', 'r', 'e', 'a', 'm', +'i', 'n', 'g', '\030', '\005', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\017', 'c', 'l', 'i', 'e', 'n', 't', 'S', +'t', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\022', '0', '\n', '\020', 's', 'e', 'r', 'v', 'e', 'r', '_', 's', 't', 'r', 'e', 'a', 'm', +'i', 'n', 'g', '\030', '\006', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\017', 's', 'e', 'r', 'v', 'e', 'r', 'S', +'t', 'r', 'e', 'a', 'm', 'i', 'n', 'g', '\"', '\312', '\t', '\n', '\013', 'F', 'i', 'l', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', +'!', '\n', '\014', 'j', 'a', 'v', 'a', '_', 'p', 'a', 'c', 'k', 'a', 'g', 'e', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\013', 'j', 'a', +'v', 'a', 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\022', '0', '\n', '\024', 'j', 'a', 'v', 'a', '_', 'o', 'u', 't', 'e', 'r', '_', 'c', +'l', 'a', 's', 's', 'n', 'a', 'm', 'e', '\030', '\010', ' ', '\001', '(', '\t', 'R', '\022', 'j', 'a', 'v', 'a', 'O', 'u', 't', 'e', 'r', +'C', 'l', 'a', 's', 's', 'n', 'a', 'm', 'e', '\022', '5', '\n', '\023', 'j', 'a', 'v', 'a', '_', 'm', 'u', 'l', 't', 'i', 'p', 'l', +'e', '_', 'f', 'i', 'l', 'e', 's', '\030', '\n', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\021', 'j', 'a', 'v', +'a', 'M', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'F', 'i', 'l', 'e', 's', '\022', 'D', '\n', '\035', 'j', 'a', 'v', 'a', '_', 'g', 'e', +'n', 'e', 'r', 'a', 't', 'e', '_', 'e', 'q', 'u', 'a', 'l', 's', '_', 'a', 'n', 'd', '_', 'h', 'a', 's', 'h', '\030', '\024', ' ', +'\001', '(', '\010', 'B', '\002', '\030', '\001', 'R', '\031', 'j', 'a', 'v', 'a', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'E', 'q', 'u', 'a', +'l', 's', 'A', 'n', 'd', 'H', 'a', 's', 'h', '\022', ':', '\n', '\026', 'j', 'a', 'v', 'a', '_', 's', 't', 'r', 'i', 'n', 'g', '_', +'c', 'h', 'e', 'c', 'k', '_', 'u', 't', 'f', '8', '\030', '\033', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\023', +'j', 'a', 'v', 'a', 'S', 't', 'r', 'i', 'n', 'g', 'C', 'h', 'e', 'c', 'k', 'U', 't', 'f', '8', '\022', 'S', '\n', '\014', 'o', 'p', +'t', 'i', 'm', 'i', 'z', 'e', '_', 'f', 'o', 'r', '\030', '\t', ' ', '\001', '(', '\016', '2', ')', '.', 'g', 'o', 'o', 'g', 'l', 'e', +'.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'l', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'O', 'p', 't', +'i', 'm', 'i', 'z', 'e', 'M', 'o', 'd', 'e', ':', '\005', 'S', 'P', 'E', 'E', 'D', 'R', '\013', 'o', 'p', 't', 'i', 'm', 'i', 'z', +'e', 'F', 'o', 'r', '\022', '\035', '\n', '\n', 'g', 'o', '_', 'p', 'a', 'c', 'k', 'a', 'g', 'e', '\030', '\013', ' ', '\001', '(', '\t', 'R', +'\t', 'g', 'o', 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\022', '5', '\n', '\023', 'c', 'c', '_', 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', +'s', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '\020', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\021', 'c', 'c', +'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '9', '\n', '\025', 'j', 'a', 'v', 'a', '_', 'g', +'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '\021', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', +'l', 's', 'e', 'R', '\023', 'j', 'a', 'v', 'a', 'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', +'5', '\n', '\023', 'p', 'y', '_', 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\030', '\022', ' ', +'\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\021', 'p', 'y', 'G', 'e', 'n', 'e', 'r', 'i', 'c', 'S', 'e', 'r', 'v', +'i', 'c', 'e', 's', '\022', '7', '\n', '\024', 'p', 'h', 'p', '_', 'g', 'e', 'n', 'e', 'r', 'i', 'c', '_', 's', 'e', 'r', 'v', 'i', +'c', 'e', 's', '\030', '*', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\022', 'p', 'h', 'p', 'G', 'e', 'n', 'e', +'r', 'i', 'c', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', +'\030', '\027', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', +'\022', '.', '\n', '\020', 'c', 'c', '_', 'e', 'n', 'a', 'b', 'l', 'e', '_', 'a', 'r', 'e', 'n', 'a', 's', '\030', '\037', ' ', '\001', '(', +'\010', ':', '\004', 't', 'r', 'u', 'e', 'R', '\016', 'c', 'c', 'E', 'n', 'a', 'b', 'l', 'e', 'A', 'r', 'e', 'n', 'a', 's', '\022', '*', +'\n', '\021', 'o', 'b', 'j', 'c', '_', 'c', 'l', 'a', 's', 's', '_', 'p', 'r', 'e', 'f', 'i', 'x', '\030', '$', ' ', '\001', '(', '\t', +'R', '\017', 'o', 'b', 'j', 'c', 'C', 'l', 'a', 's', 's', 'P', 'r', 'e', 'f', 'i', 'x', '\022', ')', '\n', '\020', 'c', 's', 'h', 'a', +'r', 'p', '_', 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\030', '%', ' ', '\001', '(', '\t', 'R', '\017', 'c', 's', 'h', 'a', 'r', +'p', 'N', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\022', '!', '\n', '\014', 's', 'w', 'i', 'f', 't', '_', 'p', 'r', 'e', 'f', 'i', +'x', '\030', '\'', ' ', '\001', '(', '\t', 'R', '\013', 's', 'w', 'i', 'f', 't', 'P', 'r', 'e', 'f', 'i', 'x', '\022', '(', '\n', '\020', 'p', +'h', 'p', '_', 'c', 'l', 'a', 's', 's', '_', 'p', 'r', 'e', 'f', 'i', 'x', '\030', '(', ' ', '\001', '(', '\t', 'R', '\016', 'p', 'h', +'p', 'C', 'l', 'a', 's', 's', 'P', 'r', 'e', 'f', 'i', 'x', '\022', '#', '\n', '\r', 'p', 'h', 'p', '_', 'n', 'a', 'm', 'e', 's', +'p', 'a', 'c', 'e', '\030', ')', ' ', '\001', '(', '\t', 'R', '\014', 'p', 'h', 'p', 'N', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\022', +'4', '\n', '\026', 'p', 'h', 'p', '_', 'm', 'e', 't', 'a', 'd', 'a', 't', 'a', '_', 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', +'\030', ',', ' ', '\001', '(', '\t', 'R', '\024', 'p', 'h', 'p', 'M', 'e', 't', 'a', 'd', 'a', 't', 'a', 'N', 'a', 'm', 'e', 's', 'p', +'a', 'c', 'e', '\022', '!', '\n', '\014', 'r', 'u', 'b', 'y', '_', 'p', 'a', 'c', 'k', 'a', 'g', 'e', '\030', '-', ' ', '\001', '(', '\t', +'R', '\013', 'r', 'u', 'b', 'y', 'P', 'a', 'c', 'k', 'a', 'g', 'e', '\022', '7', '\n', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', +'\030', '2', ' ', '\001', '(', '\013', '2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', +'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\022', 'X', '\n', '\024', 'u', +'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', +'\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', +'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', +'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', ':', '\n', '\014', 'O', 'p', 't', 'i', 'm', 'i', 'z', 'e', 'M', 'o', 'd', +'e', '\022', '\t', '\n', '\005', 'S', 'P', 'E', 'E', 'D', '\020', '\001', '\022', '\r', '\n', '\t', 'C', 'O', 'D', 'E', '_', 'S', 'I', 'Z', 'E', +'\020', '\002', '\022', '\020', '\n', '\014', 'L', 'I', 'T', 'E', '_', 'R', 'U', 'N', 'T', 'I', 'M', 'E', '\020', '\003', '*', '\t', '\010', '\350', '\007', +'\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '&', '\020', '\'', '\"', '\364', '\003', '\n', '\016', 'M', 'e', 's', 's', 'a', 'g', 'e', 'O', +'p', 't', 'i', 'o', 'n', 's', '\022', '<', '\n', '\027', 'm', 'e', 's', 's', 'a', 'g', 'e', '_', 's', 'e', 't', '_', 'w', 'i', 'r', +'e', '_', 'f', 'o', 'r', 'm', 'a', 't', '\030', '\001', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\024', 'm', 'e', +'s', 's', 'a', 'g', 'e', 'S', 'e', 't', 'W', 'i', 'r', 'e', 'F', 'o', 'r', 'm', 'a', 't', '\022', 'L', '\n', '\037', 'n', 'o', '_', +'s', 't', 'a', 'n', 'd', 'a', 'r', 'd', '_', 'd', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', '_', 'a', 'c', 'c', 'e', 's', +'s', 'o', 'r', '\030', '\002', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\034', 'n', 'o', 'S', 't', 'a', 'n', 'd', +'a', 'r', 'd', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'o', 'r', 'A', 'c', 'c', 'e', 's', 's', 'o', 'r', '\022', '%', '\n', '\n', +'d', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', +'d', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', '\033', '\n', '\t', 'm', 'a', 'p', '_', 'e', 'n', 't', 'r', 'y', '\030', '\007', +' ', '\001', '(', '\010', 'R', '\010', 'm', 'a', 'p', 'E', 'n', 't', 'r', 'y', '\022', 'V', '\n', '&', 'd', 'e', 'p', 'r', 'e', 'c', 'a', +'t', 'e', 'd', '_', 'l', 'e', 'g', 'a', 'c', 'y', '_', 'j', 's', 'o', 'n', '_', 'f', 'i', 'e', 'l', 'd', '_', 'c', 'o', 'n', +'f', 'l', 'i', 'c', 't', 's', '\030', '\013', ' ', '\001', '(', '\010', 'B', '\002', '\030', '\001', 'R', '\"', 'd', 'e', 'p', 'r', 'e', 'c', 'a', +'t', 'e', 'd', 'L', 'e', 'g', 'a', 'c', 'y', 'J', 's', 'o', 'n', 'F', 'i', 'e', 'l', 'd', 'C', 'o', 'n', 'f', 'l', 'i', 'c', +'t', 's', '\022', '7', '\n', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\030', '\014', ' ', '\001', '(', '\013', '2', '\033', '.', 'g', 'o', +'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'R', +'\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', +'d', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', +'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', +'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', +'\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\004', '\020', '\005', 'J', '\004', '\010', '\005', '\020', '\006', 'J', '\004', '\010', +'\006', '\020', '\007', 'J', '\004', '\010', '\010', '\020', '\t', 'J', '\004', '\010', '\t', '\020', '\n', '\"', '\255', '\n', '\n', '\014', 'F', 'i', 'e', 'l', 'd', +'O', 'p', 't', 'i', 'o', 'n', 's', '\022', 'A', '\n', '\005', 'c', 't', 'y', 'p', 'e', '\030', '\001', ' ', '\001', '(', '\016', '2', '#', '.', +'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', +'o', 'n', 's', '.', 'C', 'T', 'y', 'p', 'e', ':', '\006', 'S', 'T', 'R', 'I', 'N', 'G', 'R', '\005', 'c', 't', 'y', 'p', 'e', '\022', +'\026', '\n', '\006', 'p', 'a', 'c', 'k', 'e', 'd', '\030', '\002', ' ', '\001', '(', '\010', 'R', '\006', 'p', 'a', 'c', 'k', 'e', 'd', '\022', 'G', +'\n', '\006', 'j', 's', 't', 'y', 'p', 'e', '\030', '\006', ' ', '\001', '(', '\016', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', +'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'J', 'S', 'T', 'y', +'p', 'e', ':', '\t', 'J', 'S', '_', 'N', 'O', 'R', 'M', 'A', 'L', 'R', '\006', 'j', 's', 't', 'y', 'p', 'e', '\022', '\031', '\n', '\004', +'l', 'a', 'z', 'y', '\030', '\005', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\004', 'l', 'a', 'z', 'y', '\022', '.', +'\n', '\017', 'u', 'n', 'v', 'e', 'r', 'i', 'f', 'i', 'e', 'd', '_', 'l', 'a', 'z', 'y', '\030', '\017', ' ', '\001', '(', '\010', ':', '\005', +'f', 'a', 'l', 's', 'e', 'R', '\016', 'u', 'n', 'v', 'e', 'r', 'i', 'f', 'i', 'e', 'd', 'L', 'a', 'z', 'y', '\022', '%', '\n', '\n', +'d', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', +'d', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', '\031', '\n', '\004', 'w', 'e', 'a', 'k', '\030', '\n', ' ', '\001', '(', '\010', ':', +'\005', 'f', 'a', 'l', 's', 'e', 'R', '\004', 'w', 'e', 'a', 'k', '\022', '(', '\n', '\014', 'd', 'e', 'b', 'u', 'g', '_', 'r', 'e', 'd', +'a', 'c', 't', '\030', '\020', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\013', 'd', 'e', 'b', 'u', 'g', 'R', 'e', +'d', 'a', 'c', 't', '\022', 'K', '\n', '\t', 'r', 'e', 't', 'e', 'n', 't', 'i', 'o', 'n', '\030', '\021', ' ', '\001', '(', '\016', '2', '-', +'.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', +'i', 'o', 'n', 's', '.', 'O', 'p', 't', 'i', 'o', 'n', 'R', 'e', 't', 'e', 'n', 't', 'i', 'o', 'n', 'R', '\t', 'r', 'e', 't', +'e', 'n', 't', 'i', 'o', 'n', '\022', 'H', '\n', '\007', 't', 'a', 'r', 'g', 'e', 't', 's', '\030', '\023', ' ', '\003', '(', '\016', '2', '.', +'.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', +'i', 'o', 'n', 's', '.', 'O', 'p', 't', 'i', 'o', 'n', 'T', 'a', 'r', 'g', 'e', 't', 'T', 'y', 'p', 'e', 'R', '\007', 't', 'a', +'r', 'g', 'e', 't', 's', '\022', 'W', '\n', '\020', 'e', 'd', 'i', 't', 'i', 'o', 'n', '_', 'd', 'e', 'f', 'a', 'u', 'l', 't', 's', +'\030', '\024', ' ', '\003', '(', '\013', '2', ',', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', +'F', 'i', 'e', 'l', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', '.', 'E', 'd', 'i', 't', 'i', 'o', 'n', 'D', 'e', 'f', 'a', 'u', +'l', 't', 'R', '\017', 'e', 'd', 'i', 't', 'i', 'o', 'n', 'D', 'e', 'f', 'a', 'u', 'l', 't', 's', '\022', '7', '\n', '\010', 'f', 'e', +'a', 't', 'u', 'r', 'e', 's', '\030', '\025', ' ', '\001', '(', '\013', '2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', +'t', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', +'s', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', +'\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', +'.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', +'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\032', 'Z', '\n', '\016', 'E', 'd', 'i', 't', 'i', +'o', 'n', 'D', 'e', 'f', 'a', 'u', 'l', 't', '\022', '2', '\n', '\007', 'e', 'd', 'i', 't', 'i', 'o', 'n', '\030', '\003', ' ', '\001', '(', +'\016', '2', '\030', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'd', 'i', 't', 'i', +'o', 'n', 'R', '\007', 'e', 'd', 'i', 't', 'i', 'o', 'n', '\022', '\024', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\001', '(', +'\t', 'R', '\005', 'v', 'a', 'l', 'u', 'e', '\"', '/', '\n', '\005', 'C', 'T', 'y', 'p', 'e', '\022', '\n', '\n', '\006', 'S', 'T', 'R', 'I', +'N', 'G', '\020', '\000', '\022', '\010', '\n', '\004', 'C', 'O', 'R', 'D', '\020', '\001', '\022', '\020', '\n', '\014', 'S', 'T', 'R', 'I', 'N', 'G', '_', +'P', 'I', 'E', 'C', 'E', '\020', '\002', '\"', '5', '\n', '\006', 'J', 'S', 'T', 'y', 'p', 'e', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'N', +'O', 'R', 'M', 'A', 'L', '\020', '\000', '\022', '\r', '\n', '\t', 'J', 'S', '_', 'S', 'T', 'R', 'I', 'N', 'G', '\020', '\001', '\022', '\r', '\n', +'\t', 'J', 'S', '_', 'N', 'U', 'M', 'B', 'E', 'R', '\020', '\002', '\"', 'U', '\n', '\017', 'O', 'p', 't', 'i', 'o', 'n', 'R', 'e', 't', +'e', 'n', 't', 'i', 'o', 'n', '\022', '\025', '\n', '\021', 'R', 'E', 'T', 'E', 'N', 'T', 'I', 'O', 'N', '_', 'U', 'N', 'K', 'N', 'O', +'W', 'N', '\020', '\000', '\022', '\025', '\n', '\021', 'R', 'E', 'T', 'E', 'N', 'T', 'I', 'O', 'N', '_', 'R', 'U', 'N', 'T', 'I', 'M', 'E', +'\020', '\001', '\022', '\024', '\n', '\020', 'R', 'E', 'T', 'E', 'N', 'T', 'I', 'O', 'N', '_', 'S', 'O', 'U', 'R', 'C', 'E', '\020', '\002', '\"', +'\214', '\002', '\n', '\020', 'O', 'p', 't', 'i', 'o', 'n', 'T', 'a', 'r', 'g', 'e', 't', 'T', 'y', 'p', 'e', '\022', '\027', '\n', '\023', 'T', +'A', 'R', 'G', 'E', 'T', '_', 'T', 'Y', 'P', 'E', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\024', '\n', '\020', 'T', +'A', 'R', 'G', 'E', 'T', '_', 'T', 'Y', 'P', 'E', '_', 'F', 'I', 'L', 'E', '\020', '\001', '\022', '\037', '\n', '\033', 'T', 'A', 'R', 'G', +'E', 'T', '_', 'T', 'Y', 'P', 'E', '_', 'E', 'X', 'T', 'E', 'N', 'S', 'I', 'O', 'N', '_', 'R', 'A', 'N', 'G', 'E', '\020', '\002', +'\022', '\027', '\n', '\023', 'T', 'A', 'R', 'G', 'E', 'T', '_', 'T', 'Y', 'P', 'E', '_', 'M', 'E', 'S', 'S', 'A', 'G', 'E', '\020', '\003', +'\022', '\025', '\n', '\021', 'T', 'A', 'R', 'G', 'E', 'T', '_', 'T', 'Y', 'P', 'E', '_', 'F', 'I', 'E', 'L', 'D', '\020', '\004', '\022', '\025', +'\n', '\021', 'T', 'A', 'R', 'G', 'E', 'T', '_', 'T', 'Y', 'P', 'E', '_', 'O', 'N', 'E', 'O', 'F', '\020', '\005', '\022', '\024', '\n', '\020', +'T', 'A', 'R', 'G', 'E', 'T', '_', 'T', 'Y', 'P', 'E', '_', 'E', 'N', 'U', 'M', '\020', '\006', '\022', '\032', '\n', '\026', 'T', 'A', 'R', +'G', 'E', 'T', '_', 'T', 'Y', 'P', 'E', '_', 'E', 'N', 'U', 'M', '_', 'E', 'N', 'T', 'R', 'Y', '\020', '\007', '\022', '\027', '\n', '\023', +'T', 'A', 'R', 'G', 'E', 'T', '_', 'T', 'Y', 'P', 'E', '_', 'S', 'E', 'R', 'V', 'I', 'C', 'E', '\020', '\010', '\022', '\026', '\n', '\022', +'T', 'A', 'R', 'G', 'E', 'T', '_', 'T', 'Y', 'P', 'E', '_', 'M', 'E', 'T', 'H', 'O', 'D', '\020', '\t', '*', '\t', '\010', '\350', '\007', +'\020', '\200', '\200', '\200', '\200', '\002', 'J', '\004', '\010', '\004', '\020', '\005', 'J', '\004', '\010', '\022', '\020', '\023', '\"', '\254', '\001', '\n', '\014', 'O', 'n', +'e', 'o', 'f', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '7', '\n', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\030', '\001', ' ', +'\001', '(', '\013', '2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', +'t', 'u', 'r', 'e', 'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', +'t', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', +'.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', +'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', +'d', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\321', '\002', '\n', '\013', 'E', 'n', +'u', 'm', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '\037', '\n', '\013', 'a', 'l', 'l', 'o', 'w', '_', 'a', 'l', 'i', 'a', 's', '\030', +'\002', ' ', '\001', '(', '\010', 'R', '\n', 'a', 'l', 'l', 'o', 'w', 'A', 'l', 'i', 'a', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', +'e', 'c', 'a', 't', 'e', 'd', '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', +'e', 'c', 'a', 't', 'e', 'd', '\022', 'V', '\n', '&', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '_', 'l', 'e', 'g', 'a', +'c', 'y', '_', 'j', 's', 'o', 'n', '_', 'f', 'i', 'e', 'l', 'd', '_', 'c', 'o', 'n', 'f', 'l', 'i', 'c', 't', 's', '\030', '\006', +' ', '\001', '(', '\010', 'B', '\002', '\030', '\001', 'R', '\"', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', 'L', 'e', 'g', 'a', 'c', +'y', 'J', 's', 'o', 'n', 'F', 'i', 'e', 'l', 'd', 'C', 'o', 'n', 'f', 'l', 'i', 'c', 't', 's', '\022', '7', '\n', '\010', 'f', 'e', +'a', 't', 'u', 'r', 'e', 's', '\030', '\007', ' ', '\001', '(', '\013', '2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', +'t', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', +'s', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', +'\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', +'.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', +'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', +'\200', '\002', 'J', '\004', '\010', '\005', '\020', '\006', '\"', '\201', '\002', '\n', '\020', 'E', 'n', 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'O', 'p', 't', +'i', 'o', 'n', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '\001', ' ', '\001', '(', '\010', ':', +'\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', '7', '\n', '\010', 'f', 'e', 'a', +'t', 'u', 'r', 'e', 's', '\030', '\002', ' ', '\001', '(', '\013', '2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', +'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', +'\022', '(', '\n', '\014', 'd', 'e', 'b', 'u', 'g', '_', 'r', 'e', 'd', 'a', 'c', 't', '\030', '\003', ' ', '\001', '(', '\010', ':', '\005', 'f', +'a', 'l', 's', 'e', 'R', '\013', 'd', 'e', 'b', 'u', 'g', 'R', 'e', 'd', 'a', 'c', 't', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', +'t', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', +'.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', +'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', +'d', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\325', '\001', '\n', '\016', 'S', 'e', +'r', 'v', 'i', 'c', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '7', '\n', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\030', +'\"', ' ', '\001', '(', '\013', '2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', +'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\022', '%', '\n', '\n', 'd', 'e', +'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '!', ' ', '\001', '(', '\010', ':', '\005', 'f', 'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', +'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', -'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\"', 'P', -'\n', '\020', 'I', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', 'v', 'e', 'l', '\022', '\027', '\n', '\023', 'I', 'D', 'E', -'M', 'P', 'O', 'T', 'E', 'N', 'C', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\023', '\n', '\017', 'N', 'O', '_', -'S', 'I', 'D', 'E', '_', 'E', 'F', 'F', 'E', 'C', 'T', 'S', '\020', '\001', '\022', '\016', '\n', '\n', 'I', 'D', 'E', 'M', 'P', 'O', 'T', -'E', 'N', 'T', '\020', '\002', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\232', '\003', '\n', '\023', 'U', 'n', 'i', 'n', -'t', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\022', 'A', '\n', '\004', 'n', 'a', 'm', 'e', '\030', '\002', -' ', '\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', -'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '.', 'N', 'a', 'm', 'e', 'P', 'a', 'r', -'t', 'R', '\004', 'n', 'a', 'm', 'e', '\022', ')', '\n', '\020', 'i', 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', '_', 'v', 'a', 'l', -'u', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\017', 'i', 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', 'V', 'a', 'l', 'u', 'e', -'\022', ',', '\n', '\022', 'p', 'o', 's', 'i', 't', 'i', 'v', 'e', '_', 'i', 'n', 't', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\004', ' ', -'\001', '(', '\004', 'R', '\020', 'p', 'o', 's', 'i', 't', 'i', 'v', 'e', 'I', 'n', 't', 'V', 'a', 'l', 'u', 'e', '\022', ',', '\n', '\022', -'n', 'e', 'g', 'a', 't', 'i', 'v', 'e', '_', 'i', 'n', 't', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\005', ' ', '\001', '(', '\003', 'R', -'\020', 'n', 'e', 'g', 'a', 't', 'i', 'v', 'e', 'I', 'n', 't', 'V', 'a', 'l', 'u', 'e', '\022', '!', '\n', '\014', 'd', 'o', 'u', 'b', -'l', 'e', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\006', ' ', '\001', '(', '\001', 'R', '\013', 'd', 'o', 'u', 'b', 'l', 'e', 'V', 'a', 'l', -'u', 'e', '\022', '!', '\n', '\014', 's', 't', 'r', 'i', 'n', 'g', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\007', ' ', '\001', '(', '\014', 'R', -'\013', 's', 't', 'r', 'i', 'n', 'g', 'V', 'a', 'l', 'u', 'e', '\022', '\'', '\n', '\017', 'a', 'g', 'g', 'r', 'e', 'g', 'a', 't', 'e', -'_', 'v', 'a', 'l', 'u', 'e', '\030', '\010', ' ', '\001', '(', '\t', 'R', '\016', 'a', 'g', 'g', 'r', 'e', 'g', 'a', 't', 'e', 'V', 'a', -'l', 'u', 'e', '\032', 'J', '\n', '\010', 'N', 'a', 'm', 'e', 'P', 'a', 'r', 't', '\022', '\033', '\n', '\t', 'n', 'a', 'm', 'e', '_', 'p', -'a', 'r', 't', '\030', '\001', ' ', '\002', '(', '\t', 'R', '\010', 'n', 'a', 'm', 'e', 'P', 'a', 'r', 't', '\022', '!', '\n', '\014', 'i', 's', -'_', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\002', ' ', '\002', '(', '\010', 'R', '\013', 'i', 's', 'E', 'x', 't', 'e', 'n', -'s', 'i', 'o', 'n', '\"', '\374', '\t', '\n', '\n', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', '\022', '\213', '\001', '\n', '\016', 'f', -'i', 'e', 'l', 'd', '_', 'p', 'r', 'e', 's', 'e', 'n', 'c', 'e', '\030', '\001', ' ', '\001', '(', '\016', '2', ')', '.', 'g', 'o', 'o', -'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', '.', 'F', -'i', 'e', 'l', 'd', 'P', 'r', 'e', 's', 'e', 'n', 'c', 'e', 'B', '9', '\210', '\001', '\001', '\230', '\001', '\004', '\230', '\001', '\001', '\242', '\001', -'\r', '\022', '\010', 'E', 'X', 'P', 'L', 'I', 'C', 'I', 'T', '\030', '\346', '\007', '\242', '\001', '\r', '\022', '\010', 'I', 'M', 'P', 'L', 'I', 'C', -'I', 'T', '\030', '\347', '\007', '\242', '\001', '\r', '\022', '\010', 'E', 'X', 'P', 'L', 'I', 'C', 'I', 'T', '\030', '\350', '\007', 'R', '\r', 'f', 'i', -'e', 'l', 'd', 'P', 'r', 'e', 's', 'e', 'n', 'c', 'e', '\022', 'f', '\n', '\t', 'e', 'n', 'u', 'm', '_', 't', 'y', 'p', 'e', '\030', -'\002', ' ', '\001', '(', '\016', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', -'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', '.', 'E', 'n', 'u', 'm', 'T', 'y', 'p', 'e', 'B', '#', '\210', '\001', '\001', '\230', '\001', -'\006', '\230', '\001', '\001', '\242', '\001', '\013', '\022', '\006', 'C', 'L', 'O', 'S', 'E', 'D', '\030', '\346', '\007', '\242', '\001', '\t', '\022', '\004', 'O', 'P', -'E', 'N', '\030', '\347', '\007', 'R', '\010', 'e', 'n', 'u', 'm', 'T', 'y', 'p', 'e', '\022', '\222', '\001', '\n', '\027', 'r', 'e', 'p', 'e', 'a', -'t', 'e', 'd', '_', 'f', 'i', 'e', 'l', 'd', '_', 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g', '\030', '\003', ' ', '\001', '(', '\016', '2', -'1', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', -'S', 'e', 't', '.', 'R', 'e', 'p', 'e', 'a', 't', 'e', 'd', 'F', 'i', 'e', 'l', 'd', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', -'B', '\'', '\210', '\001', '\001', '\230', '\001', '\004', '\230', '\001', '\001', '\242', '\001', '\r', '\022', '\010', 'E', 'X', 'P', 'A', 'N', 'D', 'E', 'D', '\030', -'\346', '\007', '\242', '\001', '\013', '\022', '\006', 'P', 'A', 'C', 'K', 'E', 'D', '\030', '\347', '\007', 'R', '\025', 'r', 'e', 'p', 'e', 'a', 't', 'e', -'d', 'F', 'i', 'e', 'l', 'd', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', '\022', 'x', '\n', '\017', 'u', 't', 'f', '8', '_', 'v', 'a', -'l', 'i', 'd', 'a', 't', 'i', 'o', 'n', '\030', '\004', ' ', '\001', '(', '\016', '2', '*', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', -'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', '.', 'U', 't', 'f', '8', 'V', 'a', -'l', 'i', 'd', 'a', 't', 'i', 'o', 'n', 'B', '#', '\210', '\001', '\001', '\230', '\001', '\004', '\230', '\001', '\001', '\242', '\001', '\t', '\022', '\004', 'N', -'O', 'N', 'E', '\030', '\346', '\007', '\242', '\001', '\013', '\022', '\006', 'V', 'E', 'R', 'I', 'F', 'Y', '\030', '\347', '\007', 'R', '\016', 'u', 't', 'f', -'8', 'V', 'a', 'l', 'i', 'd', 'a', 't', 'i', 'o', 'n', '\022', 'x', '\n', '\020', 'm', 'e', 's', 's', 'a', 'g', 'e', '_', 'e', 'n', -'c', 'o', 'd', 'i', 'n', 'g', '\030', '\005', ' ', '\001', '(', '\016', '2', '+', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', -'t', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', '.', 'M', 'e', 's', 's', 'a', 'g', 'e', 'E', -'n', 'c', 'o', 'd', 'i', 'n', 'g', 'B', ' ', '\210', '\001', '\001', '\230', '\001', '\004', '\230', '\001', '\001', '\242', '\001', '\024', '\022', '\017', 'L', 'E', -'N', 'G', 'T', 'H', '_', 'P', 'R', 'E', 'F', 'I', 'X', 'E', 'D', '\030', '\346', '\007', 'R', '\017', 'm', 'e', 's', 's', 'a', 'g', 'e', -'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', '\022', '|', '\n', '\013', 'j', 's', 'o', 'n', '_', 'f', 'o', 'r', 'm', 'a', 't', '\030', '\006', -' ', '\001', '(', '\016', '2', '&', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', -'a', 't', 'u', 'r', 'e', 'S', 'e', 't', '.', 'J', 's', 'o', 'n', 'F', 'o', 'r', 'm', 'a', 't', 'B', '3', '\210', '\001', '\001', '\230', -'\001', '\003', '\230', '\001', '\006', '\230', '\001', '\001', '\242', '\001', '\027', '\022', '\022', 'L', 'E', 'G', 'A', 'C', 'Y', '_', 'B', 'E', 'S', 'T', '_', -'E', 'F', 'F', 'O', 'R', 'T', '\030', '\346', '\007', '\242', '\001', '\n', '\022', '\005', 'A', 'L', 'L', 'O', 'W', '\030', '\347', '\007', 'R', '\n', 'j', -'s', 'o', 'n', 'F', 'o', 'r', 'm', 'a', 't', '\"', '\\', '\n', '\r', 'F', 'i', 'e', 'l', 'd', 'P', 'r', 'e', 's', 'e', 'n', 'c', -'e', '\022', '\032', '\n', '\026', 'F', 'I', 'E', 'L', 'D', '_', 'P', 'R', 'E', 'S', 'E', 'N', 'C', 'E', '_', 'U', 'N', 'K', 'N', 'O', -'W', 'N', '\020', '\000', '\022', '\014', '\n', '\010', 'E', 'X', 'P', 'L', 'I', 'C', 'I', 'T', '\020', '\001', '\022', '\014', '\n', '\010', 'I', 'M', 'P', -'L', 'I', 'C', 'I', 'T', '\020', '\002', '\022', '\023', '\n', '\017', 'L', 'E', 'G', 'A', 'C', 'Y', '_', 'R', 'E', 'Q', 'U', 'I', 'R', 'E', -'D', '\020', '\003', '\"', '7', '\n', '\010', 'E', 'n', 'u', 'm', 'T', 'y', 'p', 'e', '\022', '\025', '\n', '\021', 'E', 'N', 'U', 'M', '_', 'T', -'Y', 'P', 'E', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\010', '\n', '\004', 'O', 'P', 'E', 'N', '\020', '\001', '\022', '\n', -'\n', '\006', 'C', 'L', 'O', 'S', 'E', 'D', '\020', '\002', '\"', 'V', '\n', '\025', 'R', 'e', 'p', 'e', 'a', 't', 'e', 'd', 'F', 'i', 'e', -'l', 'd', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', '\022', '#', '\n', '\037', 'R', 'E', 'P', 'E', 'A', 'T', 'E', 'D', '_', 'F', 'I', -'E', 'L', 'D', '_', 'E', 'N', 'C', 'O', 'D', 'I', 'N', 'G', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\n', '\n', -'\006', 'P', 'A', 'C', 'K', 'E', 'D', '\020', '\001', '\022', '\014', '\n', '\010', 'E', 'X', 'P', 'A', 'N', 'D', 'E', 'D', '\020', '\002', '\"', 'C', -'\n', '\016', 'U', 't', 'f', '8', 'V', 'a', 'l', 'i', 'd', 'a', 't', 'i', 'o', 'n', '\022', '\033', '\n', '\027', 'U', 'T', 'F', '8', '_', -'V', 'A', 'L', 'I', 'D', 'A', 'T', 'I', 'O', 'N', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\010', '\n', '\004', 'N', -'O', 'N', 'E', '\020', '\001', '\022', '\n', '\n', '\006', 'V', 'E', 'R', 'I', 'F', 'Y', '\020', '\002', '\"', 'S', '\n', '\017', 'M', 'e', 's', 's', -'a', 'g', 'e', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', '\022', '\034', '\n', '\030', 'M', 'E', 'S', 'S', 'A', 'G', 'E', '_', 'E', 'N', -'C', 'O', 'D', 'I', 'N', 'G', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\023', '\n', '\017', 'L', 'E', 'N', 'G', 'T', -'H', '_', 'P', 'R', 'E', 'F', 'I', 'X', 'E', 'D', '\020', '\001', '\022', '\r', '\n', '\t', 'D', 'E', 'L', 'I', 'M', 'I', 'T', 'E', 'D', -'\020', '\002', '\"', 'H', '\n', '\n', 'J', 's', 'o', 'n', 'F', 'o', 'r', 'm', 'a', 't', '\022', '\027', '\n', '\023', 'J', 'S', 'O', 'N', '_', -'F', 'O', 'R', 'M', 'A', 'T', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\t', '\n', '\005', 'A', 'L', 'L', 'O', 'W', -'\020', '\001', '\022', '\026', '\n', '\022', 'L', 'E', 'G', 'A', 'C', 'Y', '_', 'B', 'E', 'S', 'T', '_', 'E', 'F', 'F', 'O', 'R', 'T', '\020', -'\002', '*', '\006', '\010', '\350', '\007', '\020', '\351', '\007', '*', '\006', '\010', '\351', '\007', '\020', '\352', '\007', '*', '\006', '\010', '\213', 'N', '\020', '\220', 'N', -'J', '\006', '\010', '\347', '\007', '\020', '\350', '\007', '\"', '\376', '\002', '\n', '\022', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'D', 'e', -'f', 'a', 'u', 'l', 't', 's', '\022', 'X', '\n', '\010', 'd', 'e', 'f', 'a', 'u', 'l', 't', 's', '\030', '\001', ' ', '\003', '(', '\013', '2', -'<', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', -'S', 'e', 't', 'D', 'e', 'f', 'a', 'u', 'l', 't', 's', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'E', 'd', 'i', -'t', 'i', 'o', 'n', 'D', 'e', 'f', 'a', 'u', 'l', 't', 'R', '\010', 'd', 'e', 'f', 'a', 'u', 'l', 't', 's', '\022', 'A', '\n', '\017', -'m', 'i', 'n', 'i', 'm', 'u', 'm', '_', 'e', 'd', 'i', 't', 'i', 'o', 'n', '\030', '\004', ' ', '\001', '(', '\016', '2', '\030', '.', 'g', -'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'd', 'i', 't', 'i', 'o', 'n', 'R', '\016', 'm', -'i', 'n', 'i', 'm', 'u', 'm', 'E', 'd', 'i', 't', 'i', 'o', 'n', '\022', 'A', '\n', '\017', 'm', 'a', 'x', 'i', 'm', 'u', 'm', '_', -'e', 'd', 'i', 't', 'i', 'o', 'n', '\030', '\005', ' ', '\001', '(', '\016', '2', '\030', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', -'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'd', 'i', 't', 'i', 'o', 'n', 'R', '\016', 'm', 'a', 'x', 'i', 'm', 'u', 'm', 'E', 'd', -'i', 't', 'i', 'o', 'n', '\032', '\207', '\001', '\n', '\030', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'E', 'd', 'i', 't', 'i', -'o', 'n', 'D', 'e', 'f', 'a', 'u', 'l', 't', '\022', '2', '\n', '\007', 'e', 'd', 'i', 't', 'i', 'o', 'n', '\030', '\003', ' ', '\001', '(', +'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '*', '\t', +'\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\231', '\003', '\n', '\r', 'M', 'e', 't', 'h', 'o', 'd', 'O', 'p', 't', 'i', 'o', +'n', 's', '\022', '%', '\n', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\030', '!', ' ', '\001', '(', '\010', ':', '\005', 'f', +'a', 'l', 's', 'e', 'R', '\n', 'd', 'e', 'p', 'r', 'e', 'c', 'a', 't', 'e', 'd', '\022', 'q', '\n', '\021', 'i', 'd', 'e', 'm', 'p', +'o', 't', 'e', 'n', 'c', 'y', '_', 'l', 'e', 'v', 'e', 'l', '\030', '\"', ' ', '\001', '(', '\016', '2', '/', '.', 'g', 'o', 'o', 'g', +'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'M', 'e', 't', 'h', 'o', 'd', 'O', 'p', 't', 'i', 'o', 'n', 's', +'.', 'I', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', 'v', 'e', 'l', ':', '\023', 'I', 'D', 'E', 'M', 'P', 'O', +'T', 'E', 'N', 'C', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', 'R', '\020', 'i', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', +'y', 'L', 'e', 'v', 'e', 'l', '\022', '7', '\n', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\030', '#', ' ', '\001', '(', '\013', '2', +'\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', +'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\022', 'X', '\n', '\024', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', +'r', 'e', 't', 'e', 'd', '_', 'o', 'p', 't', 'i', 'o', 'n', '\030', '\347', '\007', ' ', '\003', '(', '\013', '2', '$', '.', 'g', 'o', 'o', +'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', +'d', 'O', 'p', 't', 'i', 'o', 'n', 'R', '\023', 'u', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', +'i', 'o', 'n', '\"', 'P', '\n', '\020', 'I', 'd', 'e', 'm', 'p', 'o', 't', 'e', 'n', 'c', 'y', 'L', 'e', 'v', 'e', 'l', '\022', '\027', +'\n', '\023', 'I', 'D', 'E', 'M', 'P', 'O', 'T', 'E', 'N', 'C', 'Y', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\023', +'\n', '\017', 'N', 'O', '_', 'S', 'I', 'D', 'E', '_', 'E', 'F', 'F', 'E', 'C', 'T', 'S', '\020', '\001', '\022', '\016', '\n', '\n', 'I', 'D', +'E', 'M', 'P', 'O', 'T', 'E', 'N', 'T', '\020', '\002', '*', '\t', '\010', '\350', '\007', '\020', '\200', '\200', '\200', '\200', '\002', '\"', '\232', '\003', '\n', +'\023', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '\022', 'A', '\n', '\004', 'n', +'a', 'm', 'e', '\030', '\002', ' ', '\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', +'u', 'f', '.', 'U', 'n', 'i', 'n', 't', 'e', 'r', 'p', 'r', 'e', 't', 'e', 'd', 'O', 'p', 't', 'i', 'o', 'n', '.', 'N', 'a', +'m', 'e', 'P', 'a', 'r', 't', 'R', '\004', 'n', 'a', 'm', 'e', '\022', ')', '\n', '\020', 'i', 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', +'r', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\017', 'i', 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', +'V', 'a', 'l', 'u', 'e', '\022', ',', '\n', '\022', 'p', 'o', 's', 'i', 't', 'i', 'v', 'e', '_', 'i', 'n', 't', '_', 'v', 'a', 'l', +'u', 'e', '\030', '\004', ' ', '\001', '(', '\004', 'R', '\020', 'p', 'o', 's', 'i', 't', 'i', 'v', 'e', 'I', 'n', 't', 'V', 'a', 'l', 'u', +'e', '\022', ',', '\n', '\022', 'n', 'e', 'g', 'a', 't', 'i', 'v', 'e', '_', 'i', 'n', 't', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\005', +' ', '\001', '(', '\003', 'R', '\020', 'n', 'e', 'g', 'a', 't', 'i', 'v', 'e', 'I', 'n', 't', 'V', 'a', 'l', 'u', 'e', '\022', '!', '\n', +'\014', 'd', 'o', 'u', 'b', 'l', 'e', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\006', ' ', '\001', '(', '\001', 'R', '\013', 'd', 'o', 'u', 'b', +'l', 'e', 'V', 'a', 'l', 'u', 'e', '\022', '!', '\n', '\014', 's', 't', 'r', 'i', 'n', 'g', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\007', +' ', '\001', '(', '\014', 'R', '\013', 's', 't', 'r', 'i', 'n', 'g', 'V', 'a', 'l', 'u', 'e', '\022', '\'', '\n', '\017', 'a', 'g', 'g', 'r', +'e', 'g', 'a', 't', 'e', '_', 'v', 'a', 'l', 'u', 'e', '\030', '\010', ' ', '\001', '(', '\t', 'R', '\016', 'a', 'g', 'g', 'r', 'e', 'g', +'a', 't', 'e', 'V', 'a', 'l', 'u', 'e', '\032', 'J', '\n', '\010', 'N', 'a', 'm', 'e', 'P', 'a', 'r', 't', '\022', '\033', '\n', '\t', 'n', +'a', 'm', 'e', '_', 'p', 'a', 'r', 't', '\030', '\001', ' ', '\002', '(', '\t', 'R', '\010', 'n', 'a', 'm', 'e', 'P', 'a', 'r', 't', '\022', +'!', '\n', '\014', 'i', 's', '_', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\030', '\002', ' ', '\002', '(', '\010', 'R', '\013', 'i', 's', +'E', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', '\"', '\374', '\t', '\n', '\n', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', '\022', +'\213', '\001', '\n', '\016', 'f', 'i', 'e', 'l', 'd', '_', 'p', 'r', 'e', 's', 'e', 'n', 'c', 'e', '\030', '\001', ' ', '\001', '(', '\016', '2', +')', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', +'S', 'e', 't', '.', 'F', 'i', 'e', 'l', 'd', 'P', 'r', 'e', 's', 'e', 'n', 'c', 'e', 'B', '9', '\210', '\001', '\001', '\230', '\001', '\004', +'\230', '\001', '\001', '\242', '\001', '\r', '\022', '\010', 'E', 'X', 'P', 'L', 'I', 'C', 'I', 'T', '\030', '\346', '\007', '\242', '\001', '\r', '\022', '\010', 'I', +'M', 'P', 'L', 'I', 'C', 'I', 'T', '\030', '\347', '\007', '\242', '\001', '\r', '\022', '\010', 'E', 'X', 'P', 'L', 'I', 'C', 'I', 'T', '\030', '\350', +'\007', 'R', '\r', 'f', 'i', 'e', 'l', 'd', 'P', 'r', 'e', 's', 'e', 'n', 'c', 'e', '\022', 'f', '\n', '\t', 'e', 'n', 'u', 'm', '_', +'t', 'y', 'p', 'e', '\030', '\002', ' ', '\001', '(', '\016', '2', '$', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', +'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', '.', 'E', 'n', 'u', 'm', 'T', 'y', 'p', 'e', 'B', '#', +'\210', '\001', '\001', '\230', '\001', '\006', '\230', '\001', '\001', '\242', '\001', '\013', '\022', '\006', 'C', 'L', 'O', 'S', 'E', 'D', '\030', '\346', '\007', '\242', '\001', +'\t', '\022', '\004', 'O', 'P', 'E', 'N', '\030', '\347', '\007', 'R', '\010', 'e', 'n', 'u', 'm', 'T', 'y', 'p', 'e', '\022', '\222', '\001', '\n', '\027', +'r', 'e', 'p', 'e', 'a', 't', 'e', 'd', '_', 'f', 'i', 'e', 'l', 'd', '_', 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g', '\030', '\003', +' ', '\001', '(', '\016', '2', '1', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', +'a', 't', 'u', 'r', 'e', 'S', 'e', 't', '.', 'R', 'e', 'p', 'e', 'a', 't', 'e', 'd', 'F', 'i', 'e', 'l', 'd', 'E', 'n', 'c', +'o', 'd', 'i', 'n', 'g', 'B', '\'', '\210', '\001', '\001', '\230', '\001', '\004', '\230', '\001', '\001', '\242', '\001', '\r', '\022', '\010', 'E', 'X', 'P', 'A', +'N', 'D', 'E', 'D', '\030', '\346', '\007', '\242', '\001', '\013', '\022', '\006', 'P', 'A', 'C', 'K', 'E', 'D', '\030', '\347', '\007', 'R', '\025', 'r', 'e', +'p', 'e', 'a', 't', 'e', 'd', 'F', 'i', 'e', 'l', 'd', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', '\022', 'x', '\n', '\017', 'u', 't', +'f', '8', '_', 'v', 'a', 'l', 'i', 'd', 'a', 't', 'i', 'o', 'n', '\030', '\004', ' ', '\001', '(', '\016', '2', '*', '.', 'g', 'o', 'o', +'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', '.', 'U', +'t', 'f', '8', 'V', 'a', 'l', 'i', 'd', 'a', 't', 'i', 'o', 'n', 'B', '#', '\210', '\001', '\001', '\230', '\001', '\004', '\230', '\001', '\001', '\242', +'\001', '\t', '\022', '\004', 'N', 'O', 'N', 'E', '\030', '\346', '\007', '\242', '\001', '\013', '\022', '\006', 'V', 'E', 'R', 'I', 'F', 'Y', '\030', '\347', '\007', +'R', '\016', 'u', 't', 'f', '8', 'V', 'a', 'l', 'i', 'd', 'a', 't', 'i', 'o', 'n', '\022', 'x', '\n', '\020', 'm', 'e', 's', 's', 'a', +'g', 'e', '_', 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g', '\030', '\005', ' ', '\001', '(', '\016', '2', '+', '.', 'g', 'o', 'o', 'g', 'l', +'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', '.', 'M', 'e', 's', +'s', 'a', 'g', 'e', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', 'B', ' ', '\210', '\001', '\001', '\230', '\001', '\004', '\230', '\001', '\001', '\242', '\001', +'\024', '\022', '\017', 'L', 'E', 'N', 'G', 'T', 'H', '_', 'P', 'R', 'E', 'F', 'I', 'X', 'E', 'D', '\030', '\346', '\007', 'R', '\017', 'm', 'e', +'s', 's', 'a', 'g', 'e', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', '\022', '|', '\n', '\013', 'j', 's', 'o', 'n', '_', 'f', 'o', 'r', +'m', 'a', 't', '\030', '\006', ' ', '\001', '(', '\016', '2', '&', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', +'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', '.', 'J', 's', 'o', 'n', 'F', 'o', 'r', 'm', 'a', 't', 'B', +'3', '\210', '\001', '\001', '\230', '\001', '\003', '\230', '\001', '\006', '\230', '\001', '\001', '\242', '\001', '\027', '\022', '\022', 'L', 'E', 'G', 'A', 'C', 'Y', '_', +'B', 'E', 'S', 'T', '_', 'E', 'F', 'F', 'O', 'R', 'T', '\030', '\346', '\007', '\242', '\001', '\n', '\022', '\005', 'A', 'L', 'L', 'O', 'W', '\030', +'\347', '\007', 'R', '\n', 'j', 's', 'o', 'n', 'F', 'o', 'r', 'm', 'a', 't', '\"', '\\', '\n', '\r', 'F', 'i', 'e', 'l', 'd', 'P', 'r', +'e', 's', 'e', 'n', 'c', 'e', '\022', '\032', '\n', '\026', 'F', 'I', 'E', 'L', 'D', '_', 'P', 'R', 'E', 'S', 'E', 'N', 'C', 'E', '_', +'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\014', '\n', '\010', 'E', 'X', 'P', 'L', 'I', 'C', 'I', 'T', '\020', '\001', '\022', '\014', +'\n', '\010', 'I', 'M', 'P', 'L', 'I', 'C', 'I', 'T', '\020', '\002', '\022', '\023', '\n', '\017', 'L', 'E', 'G', 'A', 'C', 'Y', '_', 'R', 'E', +'Q', 'U', 'I', 'R', 'E', 'D', '\020', '\003', '\"', '7', '\n', '\010', 'E', 'n', 'u', 'm', 'T', 'y', 'p', 'e', '\022', '\025', '\n', '\021', 'E', +'N', 'U', 'M', '_', 'T', 'Y', 'P', 'E', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\010', '\n', '\004', 'O', 'P', 'E', +'N', '\020', '\001', '\022', '\n', '\n', '\006', 'C', 'L', 'O', 'S', 'E', 'D', '\020', '\002', '\"', 'V', '\n', '\025', 'R', 'e', 'p', 'e', 'a', 't', +'e', 'd', 'F', 'i', 'e', 'l', 'd', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', '\022', '#', '\n', '\037', 'R', 'E', 'P', 'E', 'A', 'T', +'E', 'D', '_', 'F', 'I', 'E', 'L', 'D', '_', 'E', 'N', 'C', 'O', 'D', 'I', 'N', 'G', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', +'\020', '\000', '\022', '\n', '\n', '\006', 'P', 'A', 'C', 'K', 'E', 'D', '\020', '\001', '\022', '\014', '\n', '\010', 'E', 'X', 'P', 'A', 'N', 'D', 'E', +'D', '\020', '\002', '\"', 'C', '\n', '\016', 'U', 't', 'f', '8', 'V', 'a', 'l', 'i', 'd', 'a', 't', 'i', 'o', 'n', '\022', '\033', '\n', '\027', +'U', 'T', 'F', '8', '_', 'V', 'A', 'L', 'I', 'D', 'A', 'T', 'I', 'O', 'N', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', +'\022', '\n', '\n', '\006', 'V', 'E', 'R', 'I', 'F', 'Y', '\020', '\002', '\022', '\010', '\n', '\004', 'N', 'O', 'N', 'E', '\020', '\003', '\"', 'S', '\n', +'\017', 'M', 'e', 's', 's', 'a', 'g', 'e', 'E', 'n', 'c', 'o', 'd', 'i', 'n', 'g', '\022', '\034', '\n', '\030', 'M', 'E', 'S', 'S', 'A', +'G', 'E', '_', 'E', 'N', 'C', 'O', 'D', 'I', 'N', 'G', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\023', '\n', '\017', +'L', 'E', 'N', 'G', 'T', 'H', '_', 'P', 'R', 'E', 'F', 'I', 'X', 'E', 'D', '\020', '\001', '\022', '\r', '\n', '\t', 'D', 'E', 'L', 'I', +'M', 'I', 'T', 'E', 'D', '\020', '\002', '\"', 'H', '\n', '\n', 'J', 's', 'o', 'n', 'F', 'o', 'r', 'm', 'a', 't', '\022', '\027', '\n', '\023', +'J', 'S', 'O', 'N', '_', 'F', 'O', 'R', 'M', 'A', 'T', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\t', '\n', '\005', +'A', 'L', 'L', 'O', 'W', '\020', '\001', '\022', '\026', '\n', '\022', 'L', 'E', 'G', 'A', 'C', 'Y', '_', 'B', 'E', 'S', 'T', '_', 'E', 'F', +'F', 'O', 'R', 'T', '\020', '\002', '*', '\006', '\010', '\350', '\007', '\020', '\351', '\007', '*', '\006', '\010', '\351', '\007', '\020', '\352', '\007', '*', '\006', '\010', +'\213', 'N', '\020', '\220', 'N', 'J', '\006', '\010', '\347', '\007', '\020', '\350', '\007', '\"', '\376', '\002', '\n', '\022', 'F', 'e', 'a', 't', 'u', 'r', 'e', +'S', 'e', 't', 'D', 'e', 'f', 'a', 'u', 'l', 't', 's', '\022', 'X', '\n', '\010', 'd', 'e', 'f', 'a', 'u', 'l', 't', 's', '\030', '\001', +' ', '\003', '(', '\013', '2', '<', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', +'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'D', 'e', 'f', 'a', 'u', 'l', 't', 's', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', +'e', 't', 'E', 'd', 'i', 't', 'i', 'o', 'n', 'D', 'e', 'f', 'a', 'u', 'l', 't', 'R', '\010', 'd', 'e', 'f', 'a', 'u', 'l', 't', +'s', '\022', 'A', '\n', '\017', 'm', 'i', 'n', 'i', 'm', 'u', 'm', '_', 'e', 'd', 'i', 't', 'i', 'o', 'n', '\030', '\004', ' ', '\001', '(', '\016', '2', '\030', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'd', 'i', 't', 'i', -'o', 'n', 'R', '\007', 'e', 'd', 'i', 't', 'i', 'o', 'n', '\022', '7', '\n', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\030', '\002', -' ', '\001', '(', '\013', '2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'F', 'e', -'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\"', '\247', '\002', '\n', '\016', 'S', 'o', -'u', 'r', 'c', 'e', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'D', '\n', '\010', 'l', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\030', -'\001', ' ', '\003', '(', '\013', '2', '(', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'S', -'o', 'u', 'r', 'c', 'e', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'L', 'o', 'c', 'a', 't', 'i', 'o', 'n', 'R', '\010', 'l', -'o', 'c', 'a', 't', 'i', 'o', 'n', '\032', '\316', '\001', '\n', '\010', 'L', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\022', '\026', '\n', '\004', 'p', -'a', 't', 'h', '\030', '\001', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', 't', 'h', '\022', '\026', '\n', '\004', 's', 'p', -'a', 'n', '\030', '\002', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 's', 'p', 'a', 'n', '\022', ')', '\n', '\020', 'l', 'e', 'a', -'d', 'i', 'n', 'g', '_', 'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\017', 'l', 'e', 'a', 'd', -'i', 'n', 'g', 'C', 'o', 'm', 'm', 'e', 'n', 't', 's', '\022', '+', '\n', '\021', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', '_', 'c', -'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\004', ' ', '\001', '(', '\t', 'R', '\020', 't', 'r', 'a', 'i', 'l', 'i', 'n', 'g', 'C', 'o', -'m', 'm', 'e', 'n', 't', 's', '\022', ':', '\n', '\031', 'l', 'e', 'a', 'd', 'i', 'n', 'g', '_', 'd', 'e', 't', 'a', 'c', 'h', 'e', -'d', '_', 'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\006', ' ', '\003', '(', '\t', 'R', '\027', 'l', 'e', 'a', 'd', 'i', 'n', 'g', -'D', 'e', 't', 'a', 'c', 'h', 'e', 'd', 'C', 'o', 'm', 'm', 'e', 'n', 't', 's', '\"', '\320', '\002', '\n', '\021', 'G', 'e', 'n', 'e', -'r', 'a', 't', 'e', 'd', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'M', '\n', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', -'o', 'n', '\030', '\001', ' ', '\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', -'f', '.', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'A', 'n', 'n', 'o', 't', -'a', 't', 'i', 'o', 'n', 'R', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\032', '\353', '\001', '\n', '\n', 'A', 'n', 'n', -'o', 't', 'a', 't', 'i', 'o', 'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', '\030', '\001', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', -'R', '\004', 'p', 'a', 't', 'h', '\022', '\037', '\n', '\013', 's', 'o', 'u', 'r', 'c', 'e', '_', 'f', 'i', 'l', 'e', '\030', '\002', ' ', '\001', -'(', '\t', 'R', '\n', 's', 'o', 'u', 'r', 'c', 'e', 'F', 'i', 'l', 'e', '\022', '\024', '\n', '\005', 'b', 'e', 'g', 'i', 'n', '\030', '\003', -' ', '\001', '(', '\005', 'R', '\005', 'b', 'e', 'g', 'i', 'n', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\004', ' ', '\001', '(', '\005', 'R', -'\003', 'e', 'n', 'd', '\022', 'R', '\n', '\010', 's', 'e', 'm', 'a', 'n', 't', 'i', 'c', '\030', '\005', ' ', '\001', '(', '\016', '2', '6', '.', -'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', -'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '.', 'S', 'e', 'm', 'a', 'n', -'t', 'i', 'c', 'R', '\010', 's', 'e', 'm', 'a', 'n', 't', 'i', 'c', '\"', '(', '\n', '\010', 'S', 'e', 'm', 'a', 'n', 't', 'i', 'c', -'\022', '\010', '\n', '\004', 'N', 'O', 'N', 'E', '\020', '\000', '\022', '\007', '\n', '\003', 'S', 'E', 'T', '\020', '\001', '\022', '\t', '\n', '\005', 'A', 'L', -'I', 'A', 'S', '\020', '\002', '*', '\352', '\001', '\n', '\007', 'E', 'd', 'i', 't', 'i', 'o', 'n', '\022', '\023', '\n', '\017', 'E', 'D', 'I', 'T', -'I', 'O', 'N', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\023', '\n', '\016', 'E', 'D', 'I', 'T', 'I', 'O', 'N', '_', -'P', 'R', 'O', 'T', 'O', '2', '\020', '\346', '\007', '\022', '\023', '\n', '\016', 'E', 'D', 'I', 'T', 'I', 'O', 'N', '_', 'P', 'R', 'O', 'T', -'O', '3', '\020', '\347', '\007', '\022', '\021', '\n', '\014', 'E', 'D', 'I', 'T', 'I', 'O', 'N', '_', '2', '0', '2', '3', '\020', '\350', '\007', '\022', -'\027', '\n', '\023', 'E', 'D', 'I', 'T', 'I', 'O', 'N', '_', '1', '_', 'T', 'E', 'S', 'T', '_', 'O', 'N', 'L', 'Y', '\020', '\001', '\022', -'\027', '\n', '\023', 'E', 'D', 'I', 'T', 'I', 'O', 'N', '_', '2', '_', 'T', 'E', 'S', 'T', '_', 'O', 'N', 'L', 'Y', '\020', '\002', '\022', -'\035', '\n', '\027', 'E', 'D', 'I', 'T', 'I', 'O', 'N', '_', '9', '9', '9', '9', '7', '_', 'T', 'E', 'S', 'T', '_', 'O', 'N', 'L', -'Y', '\020', '\235', '\215', '\006', '\022', '\035', '\n', '\027', 'E', 'D', 'I', 'T', 'I', 'O', 'N', '_', '9', '9', '9', '9', '8', '_', 'T', 'E', -'S', 'T', '_', 'O', 'N', 'L', 'Y', '\020', '\236', '\215', '\006', '\022', '\035', '\n', '\027', 'E', 'D', 'I', 'T', 'I', 'O', 'N', '_', '9', '9', -'9', '9', '9', '_', 'T', 'E', 'S', 'T', '_', 'O', 'N', 'L', 'Y', '\020', '\237', '\215', '\006', 'B', '~', '\n', '\023', 'c', 'o', 'm', '.', -'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\020', 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', -'o', 'r', 'P', 'r', 'o', 't', 'o', 's', 'H', '\001', 'Z', '-', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', 'g', -'.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'd', 'e', 's', 'c', 'r', -'i', 'p', 't', 'o', 'r', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\032', 'G', 'o', 'o', 'g', 'l', 'e', -'.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'R', 'e', 'f', 'l', 'e', 'c', 't', 'i', 'o', 'n', +'o', 'n', 'R', '\016', 'm', 'i', 'n', 'i', 'm', 'u', 'm', 'E', 'd', 'i', 't', 'i', 'o', 'n', '\022', 'A', '\n', '\017', 'm', 'a', 'x', +'i', 'm', 'u', 'm', '_', 'e', 'd', 'i', 't', 'i', 'o', 'n', '\030', '\005', ' ', '\001', '(', '\016', '2', '\030', '.', 'g', 'o', 'o', 'g', +'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'E', 'd', 'i', 't', 'i', 'o', 'n', 'R', '\016', 'm', 'a', 'x', 'i', +'m', 'u', 'm', 'E', 'd', 'i', 't', 'i', 'o', 'n', '\032', '\207', '\001', '\n', '\030', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', +'E', 'd', 'i', 't', 'i', 'o', 'n', 'D', 'e', 'f', 'a', 'u', 'l', 't', '\022', '2', '\n', '\007', 'e', 'd', 'i', 't', 'i', 'o', 'n', +'\030', '\003', ' ', '\001', '(', '\016', '2', '\030', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', +'E', 'd', 'i', 't', 'i', 'o', 'n', 'R', '\007', 'e', 'd', 'i', 't', 'i', 'o', 'n', '\022', '7', '\n', '\010', 'f', 'e', 'a', 't', 'u', +'r', 'e', 's', '\030', '\002', ' ', '\001', '(', '\013', '2', '\033', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', +'u', 'f', '.', 'F', 'e', 'a', 't', 'u', 'r', 'e', 'S', 'e', 't', 'R', '\010', 'f', 'e', 'a', 't', 'u', 'r', 'e', 's', '\"', '\247', +'\002', '\n', '\016', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'D', '\n', '\010', 'l', 'o', 'c', 'a', +'t', 'i', 'o', 'n', '\030', '\001', ' ', '\003', '(', '\013', '2', '(', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', +'b', 'u', 'f', '.', 'S', 'o', 'u', 'r', 'c', 'e', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'L', 'o', 'c', 'a', 't', 'i', +'o', 'n', 'R', '\010', 'l', 'o', 'c', 'a', 't', 'i', 'o', 'n', '\032', '\316', '\001', '\n', '\010', 'L', 'o', 'c', 'a', 't', 'i', 'o', 'n', +'\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', '\030', '\001', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', 't', 'h', '\022', +'\026', '\n', '\004', 's', 'p', 'a', 'n', '\030', '\002', ' ', '\003', '(', '\005', 'B', '\002', '\020', '\001', 'R', '\004', 's', 'p', 'a', 'n', '\022', ')', +'\n', '\020', 'l', 'e', 'a', 'd', 'i', 'n', 'g', '_', 'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\003', ' ', '\001', '(', '\t', 'R', +'\017', 'l', 'e', 'a', 'd', 'i', 'n', 'g', 'C', 'o', 'm', 'm', 'e', 'n', 't', 's', '\022', '+', '\n', '\021', 't', 'r', 'a', 'i', 'l', +'i', 'n', 'g', '_', 'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\004', ' ', '\001', '(', '\t', 'R', '\020', 't', 'r', 'a', 'i', 'l', +'i', 'n', 'g', 'C', 'o', 'm', 'm', 'e', 'n', 't', 's', '\022', ':', '\n', '\031', 'l', 'e', 'a', 'd', 'i', 'n', 'g', '_', 'd', 'e', +'t', 'a', 'c', 'h', 'e', 'd', '_', 'c', 'o', 'm', 'm', 'e', 'n', 't', 's', '\030', '\006', ' ', '\003', '(', '\t', 'R', '\027', 'l', 'e', +'a', 'd', 'i', 'n', 'g', 'D', 'e', 't', 'a', 'c', 'h', 'e', 'd', 'C', 'o', 'm', 'm', 'e', 'n', 't', 's', '\"', '\320', '\002', '\n', +'\021', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '\022', 'M', '\n', '\n', 'a', 'n', 'n', +'o', 't', 'a', 't', 'i', 'o', 'n', '\030', '\001', ' ', '\003', '(', '\013', '2', '-', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', +'o', 't', 'o', 'b', 'u', 'f', '.', 'G', 'e', 'n', 'e', 'r', 'a', 't', 'e', 'd', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', +'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', 'R', '\n', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\032', '\353', '\001', +'\n', '\n', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '\022', '\026', '\n', '\004', 'p', 'a', 't', 'h', '\030', '\001', ' ', '\003', '(', +'\005', 'B', '\002', '\020', '\001', 'R', '\004', 'p', 'a', 't', 'h', '\022', '\037', '\n', '\013', 's', 'o', 'u', 'r', 'c', 'e', '_', 'f', 'i', 'l', +'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\n', 's', 'o', 'u', 'r', 'c', 'e', 'F', 'i', 'l', 'e', '\022', '\024', '\n', '\005', 'b', 'e', +'g', 'i', 'n', '\030', '\003', ' ', '\001', '(', '\005', 'R', '\005', 'b', 'e', 'g', 'i', 'n', '\022', '\020', '\n', '\003', 'e', 'n', 'd', '\030', '\004', +' ', '\001', '(', '\005', 'R', '\003', 'e', 'n', 'd', '\022', 'R', '\n', '\010', 's', 'e', 'm', 'a', 'n', 't', 'i', 'c', '\030', '\005', ' ', '\001', +'(', '\016', '2', '6', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'G', 'e', 'n', 'e', +'r', 'a', 't', 'e', 'd', 'C', 'o', 'd', 'e', 'I', 'n', 'f', 'o', '.', 'A', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', '.', +'S', 'e', 'm', 'a', 'n', 't', 'i', 'c', 'R', '\010', 's', 'e', 'm', 'a', 'n', 't', 'i', 'c', '\"', '(', '\n', '\010', 'S', 'e', 'm', +'a', 'n', 't', 'i', 'c', '\022', '\010', '\n', '\004', 'N', 'O', 'N', 'E', '\020', '\000', '\022', '\007', '\n', '\003', 'S', 'E', 'T', '\020', '\001', '\022', +'\t', '\n', '\005', 'A', 'L', 'I', 'A', 'S', '\020', '\002', '*', '\377', '\001', '\n', '\007', 'E', 'd', 'i', 't', 'i', 'o', 'n', '\022', '\023', '\n', +'\017', 'E', 'D', 'I', 'T', 'I', 'O', 'N', '_', 'U', 'N', 'K', 'N', 'O', 'W', 'N', '\020', '\000', '\022', '\023', '\n', '\016', 'E', 'D', 'I', +'T', 'I', 'O', 'N', '_', 'P', 'R', 'O', 'T', 'O', '2', '\020', '\346', '\007', '\022', '\023', '\n', '\016', 'E', 'D', 'I', 'T', 'I', 'O', 'N', +'_', 'P', 'R', 'O', 'T', 'O', '3', '\020', '\347', '\007', '\022', '\021', '\n', '\014', 'E', 'D', 'I', 'T', 'I', 'O', 'N', '_', '2', '0', '2', +'3', '\020', '\350', '\007', '\022', '\027', '\n', '\023', 'E', 'D', 'I', 'T', 'I', 'O', 'N', '_', '1', '_', 'T', 'E', 'S', 'T', '_', 'O', 'N', +'L', 'Y', '\020', '\001', '\022', '\027', '\n', '\023', 'E', 'D', 'I', 'T', 'I', 'O', 'N', '_', '2', '_', 'T', 'E', 'S', 'T', '_', 'O', 'N', +'L', 'Y', '\020', '\002', '\022', '\035', '\n', '\027', 'E', 'D', 'I', 'T', 'I', 'O', 'N', '_', '9', '9', '9', '9', '7', '_', 'T', 'E', 'S', +'T', '_', 'O', 'N', 'L', 'Y', '\020', '\235', '\215', '\006', '\022', '\035', '\n', '\027', 'E', 'D', 'I', 'T', 'I', 'O', 'N', '_', '9', '9', '9', +'9', '8', '_', 'T', 'E', 'S', 'T', '_', 'O', 'N', 'L', 'Y', '\020', '\236', '\215', '\006', '\022', '\035', '\n', '\027', 'E', 'D', 'I', 'T', 'I', +'O', 'N', '_', '9', '9', '9', '9', '9', '_', 'T', 'E', 'S', 'T', '_', 'O', 'N', 'L', 'Y', '\020', '\237', '\215', '\006', '\022', '\023', '\n', +'\013', 'E', 'D', 'I', 'T', 'I', 'O', 'N', '_', 'M', 'A', 'X', '\020', '\377', '\377', '\377', '\377', '\007', 'B', '~', '\n', '\023', 'c', 'o', 'm', +'.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', 'B', '\020', 'D', 'e', 's', 'c', 'r', 'i', 'p', +'t', 'o', 'r', 'P', 'r', 'o', 't', 'o', 's', 'H', '\001', 'Z', '-', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a', 'n', +'g', '.', 'o', 'r', 'g', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 't', 'y', 'p', 'e', 's', '/', 'd', 'e', 's', 'c', +'r', 'i', 'p', 't', 'o', 'r', 'p', 'b', '\370', '\001', '\001', '\242', '\002', '\003', 'G', 'P', 'B', '\252', '\002', '\032', 'G', 'o', 'o', 'g', 'l', +'e', '.', 'P', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'R', 'e', 'f', 'l', 'e', 'c', 't', 'i', 'o', 'n', }; static _upb_DefPool_Init *deps[1] = { @@ -2211,7 +2224,7 @@ _upb_DefPool_Init google_protobuf_descriptor_proto_upbdefinit = { deps, &google_protobuf_descriptor_proto_upb_file_layout, "google/protobuf/descriptor.proto", - UPB_STRINGVIEW_INIT(descriptor, 11620) + UPB_STRINGVIEW_INIT(descriptor, 11646) }; @@ -3059,6 +3072,10 @@ void upb_strtable_setentryvalue(upb_strtable* t, intptr_t iter, upb_value v) { #include #include #include +#include +#include +#include +#include #include #include @@ -3107,9 +3124,13 @@ static bool jsondec_isvalue(const upb_FieldDef* f) { jsondec_isnullvalue(f); } -UPB_NORETURN static void jsondec_err(jsondec* d, const char* msg) { +static void jsondec_seterrmsg(jsondec* d, const char* msg) { upb_Status_SetErrorFormat(d->status, "Error parsing JSON @%d:%d: %s", d->line, (int)(d->ptr - d->line_begin), msg); +} + +UPB_NORETURN static void jsondec_err(jsondec* d, const char* msg) { + jsondec_seterrmsg(d, msg); UPB_LONGJMP(d->err, 1); } @@ -3124,7 +3145,9 @@ UPB_NORETURN static void jsondec_errf(jsondec* d, const char* fmt, ...) { UPB_LONGJMP(d->err, 1); } -static void jsondec_skipws(jsondec* d) { +// Advances d->ptr until the next non-whitespace character or to the end of +// the buffer. +static void jsondec_consumews(jsondec* d) { while (d->ptr != d->end) { switch (*d->ptr) { case '\n': @@ -3140,7 +3163,16 @@ static void jsondec_skipws(jsondec* d) { return; } } - jsondec_err(d, "Unexpected EOF"); +} + +// Advances d->ptr until the next non-whitespace character. Postcondition that +// d->ptr is pointing at a valid non-whitespace character (will err if end of +// buffer is reached). +static void jsondec_skipws(jsondec* d) { + jsondec_consumews(d); + if (d->ptr == d->end) { + jsondec_err(d, "Unexpected EOF"); + } } static bool jsondec_tryparsech(jsondec* d, char ch) { @@ -3175,6 +3207,10 @@ static void jsondec_entrysep(jsondec* d) { } static int jsondec_rawpeek(jsondec* d) { + if (d->ptr == d->end) { + jsondec_err(d, "Unexpected EOF"); + } + switch (*d->ptr) { case '{': return JD_OBJECT; @@ -3290,7 +3326,7 @@ static void jsondec_skipdigits(jsondec* d) { static double jsondec_number(jsondec* d) { const char* start = d->ptr; - assert(jsondec_rawpeek(d) == JD_NUMBER); + UPB_ASSERT(jsondec_rawpeek(d) == JD_NUMBER); /* Skip over the syntax of a number, as specified by JSON. */ if (*d->ptr == '-') d->ptr++; @@ -3325,9 +3361,19 @@ parse: * (strtod() accepts a superset of JSON syntax). */ errno = 0; { + // Copy the number into a null-terminated scratch buffer since strtod + // expects a null-terminated string. + char nullz[64]; + ptrdiff_t len = d->ptr - start; + if (len > (ptrdiff_t)(sizeof(nullz) - 1)) { + jsondec_err(d, "excessively long number"); + } + memcpy(nullz, start, len); + nullz[len] = '\0'; + char* end; - double val = strtod(start, &end); - assert(end == d->ptr); + double val = strtod(nullz, &end); + UPB_ASSERT(end - nullz == len); /* Currently the min/max-val conformance tests fail if we check this. Does * this mean the conformance tests are wrong or strtod() is wrong, or @@ -3468,7 +3514,7 @@ static upb_StringView jsondec_string(jsondec* d) { } break; default: - if ((unsigned char)*d->ptr < 0x20) { + if ((unsigned char)ch < 0x20) { jsondec_err(d, "Invalid char in JSON string"); } *end++ = ch; @@ -4472,7 +4518,17 @@ static bool upb_JsonDecoder_Decode(jsondec* const d, upb_Message* const msg, if (UPB_SETJMP(d->err)) return false; jsondec_tomsg(d, msg, m); - return true; + + // Consume any trailing whitespace before checking if we read the entire + // input. + jsondec_consumews(d); + + if (d->ptr == d->end) { + return true; + } else { + jsondec_seterrmsg(d, "unexpected trailing characters"); + return false; + } } bool upb_JsonDecode(const char* buf, size_t size, upb_Message* msg, @@ -5826,32 +5882,33 @@ void upb_Arena_DecRefFor(upb_Arena* arena, const void* owner) { } +#include + // Must be last. upb_MapInsertStatus upb_Message_InsertMapEntry(upb_Map* map, const upb_MiniTable* mini_table, - const upb_MiniTableField* field, + const upb_MiniTableField* f, upb_Message* map_entry_message, upb_Arena* arena) { - const upb_MiniTable* map_entry_mini_table = - mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg; + // TODO: use a variant of upb_MiniTable_GetSubMessageTable() here. + const upb_MiniTable* map_entry_mini_table = upb_MiniTableSub_Message( + mini_table->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); UPB_ASSERT(map_entry_mini_table); - UPB_ASSERT(map_entry_mini_table->field_count == 2); + UPB_ASSERT(map_entry_mini_table->UPB_PRIVATE(field_count) == 2); const upb_MiniTableField* map_entry_key_field = - &map_entry_mini_table->fields[0]; + &map_entry_mini_table->UPB_PRIVATE(fields)[0]; const upb_MiniTableField* map_entry_value_field = - &map_entry_mini_table->fields[1]; + &map_entry_mini_table->UPB_PRIVATE(fields)[1]; // Map key/value cannot have explicit defaults, // hence assuming a zero default is valid. upb_MessageValue default_val; memset(&default_val, 0, sizeof(upb_MessageValue)); - upb_MessageValue map_entry_key; - upb_MessageValue map_entry_value; - _upb_Message_GetField(map_entry_message, map_entry_key_field, &default_val, - &map_entry_key); - _upb_Message_GetField(map_entry_message, map_entry_value_field, &default_val, - &map_entry_value); + upb_MessageValue map_entry_key = + upb_Message_GetField(map_entry_message, map_entry_key_field, default_val); + upb_MessageValue map_entry_value = upb_Message_GetField( + map_entry_message, map_entry_value_field, default_val); return upb_Map_Insert(map, map_entry_key, map_entry_value, arena); } @@ -5880,26 +5937,312 @@ bool upb_Message_IsExactlyEqual(const upb_Message* m1, const upb_Message* m2, } +#include #include + // Must be last. -const char _upb_Array_CTypeSizeLg2Table[] = { - [kUpb_CType_Bool] = 0, - [kUpb_CType_Float] = 2, - [kUpb_CType_Int32] = 2, - [kUpb_CType_UInt32] = 2, - [kUpb_CType_Enum] = 2, - [kUpb_CType_Message] = UPB_SIZE(2, 3), - [kUpb_CType_Double] = 3, - [kUpb_CType_Int64] = 3, - [kUpb_CType_UInt64] = 3, - [kUpb_CType_String] = UPB_SIZE(3, 4), - [kUpb_CType_Bytes] = UPB_SIZE(3, 4), -}; +static upb_StringView upb_Clone_StringView(upb_StringView str, + upb_Arena* arena) { + if (str.size == 0) { + return upb_StringView_FromDataAndSize(NULL, 0); + } + void* cloned_data = upb_Arena_Malloc(arena, str.size); + upb_StringView cloned_str = + upb_StringView_FromDataAndSize(cloned_data, str.size); + memcpy(cloned_data, str.data, str.size); + return cloned_str; +} + +static bool upb_Clone_MessageValue(void* value, upb_CType value_type, + const upb_MiniTable* sub, upb_Arena* arena) { + switch (value_type) { + case kUpb_CType_Bool: + case kUpb_CType_Float: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Enum: + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: + return true; + case kUpb_CType_String: + case kUpb_CType_Bytes: { + upb_StringView source = *(upb_StringView*)value; + int size = source.size; + void* cloned_data = upb_Arena_Malloc(arena, size); + if (cloned_data == NULL) { + return false; + } + *(upb_StringView*)value = + upb_StringView_FromDataAndSize(cloned_data, size); + memcpy(cloned_data, source.data, size); + return true; + } break; + case kUpb_CType_Message: { + const upb_TaggedMessagePtr source = *(upb_TaggedMessagePtr*)value; + bool is_empty = upb_TaggedMessagePtr_IsEmpty(source); + if (is_empty) sub = UPB_PRIVATE(_upb_MiniTable_Empty)(); + UPB_ASSERT(source); + upb_Message* clone = upb_Message_DeepClone( + _upb_TaggedMessagePtr_GetMessage(source), sub, arena); + *(upb_TaggedMessagePtr*)value = + _upb_TaggedMessagePtr_Pack(clone, is_empty); + return clone != NULL; + } break; + } + UPB_UNREACHABLE(); +} + +upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type, + upb_CType value_type, + const upb_MiniTable* map_entry_table, + upb_Arena* arena) { + upb_Map* cloned_map = _upb_Map_New(arena, map->key_size, map->val_size); + if (cloned_map == NULL) { + return NULL; + } + upb_MessageValue key, val; + size_t iter = kUpb_Map_Begin; + while (upb_Map_Next(map, &key, &val, &iter)) { + const upb_MiniTableField* value_field = + &map_entry_table->UPB_PRIVATE(fields)[1]; + const upb_MiniTable* value_sub = + (value_field->UPB_PRIVATE(submsg_index) != kUpb_NoSub) + ? upb_MiniTable_GetSubMessageTable(map_entry_table, value_field) + : NULL; + upb_CType value_field_type = upb_MiniTableField_CType(value_field); + if (!upb_Clone_MessageValue(&val, value_field_type, value_sub, arena)) { + return NULL; + } + if (upb_Map_Insert(cloned_map, key, val, arena) == + kUpb_MapInsertStatus_OutOfMemory) { + return NULL; + } + } + return cloned_map; +} + +static upb_Map* upb_Message_Map_DeepClone(const upb_Map* map, + const upb_MiniTable* mini_table, + const upb_MiniTableField* f, + upb_Message* clone, + upb_Arena* arena) { + // TODO: use a variant of upb_MiniTable_GetSubMessageTable() here. + const upb_MiniTable* map_entry_table = upb_MiniTableSub_Message( + mini_table->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); + UPB_ASSERT(map_entry_table); + + const upb_MiniTableField* key_field = + &map_entry_table->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* value_field = + &map_entry_table->UPB_PRIVATE(fields)[1]; + + upb_Map* cloned_map = upb_Map_DeepClone( + map, upb_MiniTableField_CType(key_field), + upb_MiniTableField_CType(value_field), map_entry_table, arena); + if (!cloned_map) { + return NULL; + } + _upb_Message_SetNonExtensionField(clone, f, &cloned_map); + return cloned_map; +} + +upb_Array* upb_Array_DeepClone(const upb_Array* array, upb_CType value_type, + const upb_MiniTable* sub, upb_Arena* arena) { + size_t size = array->size; + upb_Array* cloned_array = + UPB_PRIVATE(_upb_Array_New)(arena, size, upb_CType_SizeLg2(value_type)); + if (!cloned_array) { + return NULL; + } + if (!_upb_Array_ResizeUninitialized(cloned_array, size, arena)) { + return NULL; + } + for (size_t i = 0; i < size; ++i) { + upb_MessageValue val = upb_Array_Get(array, i); + if (!upb_Clone_MessageValue(&val, value_type, sub, arena)) { + return false; + } + upb_Array_Set(cloned_array, i, val); + } + return cloned_array; +} + +static bool upb_Message_Array_DeepClone(const upb_Array* array, + const upb_MiniTable* mini_table, + const upb_MiniTableField* field, + upb_Message* clone, upb_Arena* arena) { + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(field); + upb_Array* cloned_array = upb_Array_DeepClone( + array, upb_MiniTableField_CType(field), + upb_MiniTableField_CType(field) == kUpb_CType_Message && + field->UPB_PRIVATE(submsg_index) != kUpb_NoSub + ? upb_MiniTable_GetSubMessageTable(mini_table, field) + : NULL, + arena); + + // Clear out upb_Array* due to parent memcpy. + _upb_Message_SetNonExtensionField(clone, field, &cloned_array); + return true; +} + +static bool upb_Clone_ExtensionValue( + const upb_MiniTableExtension* mini_table_ext, + const upb_Message_Extension* source, upb_Message_Extension* dest, + upb_Arena* arena) { + dest->data = source->data; + return upb_Clone_MessageValue( + &dest->data, + upb_MiniTableField_CType(&mini_table_ext->UPB_PRIVATE(field)), + upb_MiniTableExtension_GetSubMessage(mini_table_ext), arena); +} + +upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* mini_table, + upb_Arena* arena) { + upb_StringView empty_string = upb_StringView_FromDataAndSize(NULL, 0); + // Only copy message area skipping upb_Message_Internal. + memcpy(dst, src, mini_table->UPB_PRIVATE(size)); + for (size_t i = 0; i < mini_table->UPB_PRIVATE(field_count); ++i) { + const upb_MiniTableField* field = &mini_table->UPB_PRIVATE(fields)[i]; + if (upb_MiniTableField_IsScalar(field)) { + switch (upb_MiniTableField_CType(field)) { + case kUpb_CType_Message: { + upb_TaggedMessagePtr tagged = + upb_Message_GetTaggedMessagePtr(src, field, NULL); + const upb_Message* sub_message = + _upb_TaggedMessagePtr_GetMessage(tagged); + if (sub_message != NULL) { + // If the message is currently in an unlinked, "empty" state we keep + // it that way, because we don't want to deal with decode options, + // decode status, or possible parse failure here. + bool is_empty = upb_TaggedMessagePtr_IsEmpty(tagged); + const upb_MiniTable* sub_message_table = + is_empty ? UPB_PRIVATE(_upb_MiniTable_Empty)() + : upb_MiniTable_GetSubMessageTable(mini_table, field); + upb_Message* dst_sub_message = + upb_Message_DeepClone(sub_message, sub_message_table, arena); + if (dst_sub_message == NULL) { + return NULL; + } + _upb_Message_SetTaggedMessagePtr( + dst, mini_table, field, + _upb_TaggedMessagePtr_Pack(dst_sub_message, is_empty)); + } + } break; + case kUpb_CType_String: + case kUpb_CType_Bytes: { + upb_StringView str = upb_Message_GetString(src, field, empty_string); + if (str.size != 0) { + if (!upb_Message_SetString( + dst, field, upb_Clone_StringView(str, arena), arena)) { + return NULL; + } + } + } break; + default: + // Scalar, already copied. + break; + } + } else { + if (upb_MiniTableField_IsMap(field)) { + const upb_Map* map = upb_Message_GetMap(src, field); + if (map != NULL) { + if (!upb_Message_Map_DeepClone(map, mini_table, field, dst, arena)) { + return NULL; + } + } + } else { + const upb_Array* array = upb_Message_GetArray(src, field); + if (array != NULL) { + if (!upb_Message_Array_DeepClone(array, mini_table, field, dst, + arena)) { + return NULL; + } + } + } + } + } + // Clone extensions. + size_t ext_count; + const upb_Message_Extension* ext = _upb_Message_Getexts(src, &ext_count); + for (size_t i = 0; i < ext_count; ++i) { + const upb_Message_Extension* msg_ext = &ext[i]; + const upb_MiniTableField* field = &msg_ext->ext->UPB_PRIVATE(field); + upb_Message_Extension* dst_ext = + _upb_Message_GetOrCreateExtension(dst, msg_ext->ext, arena); + if (!dst_ext) return NULL; + if (upb_MiniTableField_IsScalar(field)) { + if (!upb_Clone_ExtensionValue(msg_ext->ext, msg_ext, dst_ext, arena)) { + return NULL; + } + } else { + upb_Array* msg_array = (upb_Array*)msg_ext->data.ptr; + UPB_ASSERT(msg_array); + upb_Array* cloned_array = upb_Array_DeepClone( + msg_array, upb_MiniTableField_CType(field), + upb_MiniTableExtension_GetSubMessage(msg_ext->ext), arena); + if (!cloned_array) { + return NULL; + } + dst_ext->data.ptr = (void*)cloned_array; + } + } + + // Clone unknowns. + size_t unknown_size = 0; + const char* ptr = upb_Message_GetUnknown(src, &unknown_size); + if (unknown_size != 0) { + UPB_ASSERT(ptr); + // Make a copy into destination arena. + if (!UPB_PRIVATE(_upb_Message_AddUnknown)(dst, ptr, unknown_size, arena)) { + return NULL; + } + } + return dst; +} + +bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* mini_table, upb_Arena* arena) { + upb_Message_Clear(dst, mini_table); + return _upb_Message_Copy(dst, src, mini_table, arena) != NULL; +} + +// Deep clones a message using the provided target arena. +// +// Returns NULL on failure. +upb_Message* upb_Message_DeepClone(const upb_Message* msg, + const upb_MiniTable* m, upb_Arena* arena) { + upb_Message* clone = upb_Message_New(m, arena); + return _upb_Message_Copy(clone, msg, m, arena); +} + +// Performs a shallow copy. TODO: Extend to handle unknown fields. +void upb_Message_ShallowCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* m) { + memcpy(dst, src, m->UPB_PRIVATE(size)); +} + +// Performs a shallow clone. Ignores unknown fields. +upb_Message* upb_Message_ShallowClone(const upb_Message* msg, + const upb_MiniTable* m, + upb_Arena* arena) { + upb_Message* clone = upb_Message_New(m, arena); + upb_Message_ShallowCopy(clone, msg, m); + return clone; +} + + +#include +#include + + +// Must be last. upb_Array* upb_Array_New(upb_Arena* a, upb_CType type) { - return _upb_Array_New(a, 4, _upb_Array_CTypeSizeLg2(type)); + return UPB_PRIVATE(_upb_Array_New)(a, 4, upb_CType_SizeLg2(type)); } const void* upb_Array_DataPtr(const upb_Array* arr) { @@ -5913,7 +6256,7 @@ size_t upb_Array_Size(const upb_Array* arr) { return arr->size; } upb_MessageValue upb_Array_Get(const upb_Array* arr, size_t i) { upb_MessageValue ret; const char* data = _upb_array_constptr(arr); - int lg2 = arr->data & 7; + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr); UPB_ASSERT(i < arr->size); memcpy(&ret, data + (i << lg2), 1 << lg2); return ret; @@ -5921,14 +6264,14 @@ upb_MessageValue upb_Array_Get(const upb_Array* arr, size_t i) { void upb_Array_Set(upb_Array* arr, size_t i, upb_MessageValue val) { char* data = _upb_array_ptr(arr); - int lg2 = arr->data & 7; + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr); UPB_ASSERT(i < arr->size); memcpy(data + (i << lg2), &val, 1 << lg2); } bool upb_Array_Append(upb_Array* arr, upb_MessageValue val, upb_Arena* arena) { UPB_ASSERT(arena); - if (!upb_Array_Resize(arr, arr->size + 1, arena)) { + if (!_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } upb_Array_Set(arr, arr->size - 1, val); @@ -5937,7 +6280,7 @@ bool upb_Array_Append(upb_Array* arr, upb_MessageValue val, upb_Arena* arena) { void upb_Array_Move(upb_Array* arr, size_t dst_idx, size_t src_idx, size_t count) { - const int lg2 = arr->data & 7; + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr); char* data = _upb_array_ptr(arr); memmove(&data[dst_idx << lg2], &data[src_idx << lg2], count << lg2); } @@ -5948,7 +6291,7 @@ bool upb_Array_Insert(upb_Array* arr, size_t i, size_t count, UPB_ASSERT(i <= arr->size); UPB_ASSERT(count + arr->size >= count); const size_t oldsize = arr->size; - if (!upb_Array_Resize(arr, arr->size + count, arena)) { + if (!_upb_Array_ResizeUninitialized(arr, arr->size + count, arena)) { return false; } upb_Array_Move(arr, i + count, i, oldsize - i); @@ -5974,31 +6317,125 @@ bool upb_Array_Resize(upb_Array* arr, size_t size, upb_Arena* arena) { } const size_t newsize = arr->size; if (newsize > oldsize) { - const int lg2 = arr->data & 7; + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr); char* data = _upb_array_ptr(arr); memset(data + (oldsize << lg2), 0, (newsize - oldsize) << lg2); } return true; } -// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// - -bool _upb_array_realloc(upb_Array* arr, size_t min_capacity, upb_Arena* arena) { - size_t new_capacity = UPB_MAX(arr->capacity, 4); - int elem_size_lg2 = arr->data & 7; - size_t old_bytes = arr->capacity << elem_size_lg2; - size_t new_bytes; - void* ptr = _upb_array_ptr(arr); +bool UPB_PRIVATE(_upb_Array_Realloc)(upb_Array* array, size_t min_capacity, + upb_Arena* arena) { + size_t new_capacity = UPB_MAX(array->UPB_PRIVATE(capacity), 4); + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(array); + size_t old_bytes = array->UPB_PRIVATE(capacity) << lg2; + void* ptr = _upb_array_ptr(array); // Log2 ceiling of size. while (new_capacity < min_capacity) new_capacity *= 2; - new_bytes = new_capacity << elem_size_lg2; + const size_t new_bytes = new_capacity << lg2; ptr = upb_Arena_Realloc(arena, ptr, old_bytes, new_bytes); if (!ptr) return false; - arr->data = _upb_tag_arrptr(ptr, elem_size_lg2); - arr->capacity = new_capacity; + UPB_PRIVATE(_upb_Array_SetTaggedPtr)(array, ptr, lg2); + array->UPB_PRIVATE(capacity) = new_capacity; + return true; +} + + +#include + + +// Must be last. + +const upb_Message_Extension* _upb_Message_Getext( + const upb_Message* msg, const upb_MiniTableExtension* e) { + size_t n; + const upb_Message_Extension* ext = _upb_Message_Getexts(msg, &n); + + // For now we use linear search exclusively to find extensions. + // If this becomes an issue due to messages with lots of extensions, + // we can introduce a table of some sort. + for (size_t i = 0; i < n; i++) { + if (ext[i].ext == e) { + return &ext[i]; + } + } + + return NULL; +} + +const upb_Message_Extension* _upb_Message_Getexts(const upb_Message* msg, + size_t* count) { + const upb_Message_Internal* in = upb_Message_Getinternal(msg); + if (in->internal) { + *count = (in->internal->size - in->internal->ext_begin) / + sizeof(upb_Message_Extension); + return UPB_PTR_AT(in->internal, in->internal->ext_begin, void); + } else { + *count = 0; + return NULL; + } +} + +upb_Message_Extension* _upb_Message_GetOrCreateExtension( + upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* arena) { + upb_Message_Extension* ext = + (upb_Message_Extension*)_upb_Message_Getext(msg, e); + if (ext) return ext; + if (!UPB_PRIVATE(_upb_Message_Realloc)(msg, sizeof(upb_Message_Extension), arena)) return NULL; + upb_Message_Internal* in = upb_Message_Getinternal(msg); + in->internal->ext_begin -= sizeof(upb_Message_Extension); + ext = UPB_PTR_AT(in->internal, in->internal->ext_begin, void); + memset(ext, 0, sizeof(upb_Message_Extension)); + ext->ext = e; + return ext; +} + + +#include +#include + + +// Must be last. + +const float kUpb_FltInfinity = INFINITY; +const double kUpb_Infinity = INFINITY; +const double kUpb_NaN = NAN; + +static const size_t realloc_overhead = sizeof(upb_Message_InternalData); + +bool UPB_PRIVATE(_upb_Message_Realloc)(upb_Message* msg, size_t need, + upb_Arena* arena) { + upb_Message_Internal* in = upb_Message_Getinternal(msg); + if (!in->internal) { + // No internal data, allocate from scratch. + size_t size = UPB_MAX(128, upb_Log2CeilingSize(need + realloc_overhead)); + upb_Message_InternalData* internal = upb_Arena_Malloc(arena, size); + if (!internal) return false; + internal->size = size; + internal->unknown_end = realloc_overhead; + internal->ext_begin = size; + in->internal = internal; + } else if (in->internal->ext_begin - in->internal->unknown_end < need) { + // Internal data is too small, reallocate. + size_t new_size = upb_Log2CeilingSize(in->internal->size + need); + size_t ext_bytes = in->internal->size - in->internal->ext_begin; + size_t new_ext_begin = new_size - ext_bytes; + upb_Message_InternalData* internal = + upb_Arena_Realloc(arena, in->internal, in->internal->size, new_size); + if (!internal) return false; + if (ext_bytes) { + // Need to move extension data to the end. + char* ptr = (char*)internal; + memmove(ptr + new_ext_begin, ptr + internal->ext_begin, ext_bytes); + } + internal->ext_begin = new_ext_begin; + internal->size = new_size; + in->internal = internal; + } + UPB_ASSERT(in->internal->ext_begin - in->internal->unknown_end >= need); return true; } @@ -6115,6 +6552,9 @@ upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size) { } +#include +#include + // Must be last. @@ -6196,8 +6636,10 @@ static bool _upb_mapsorter_resize(_upb_mapsorter* s, _upb_sortedmap* sorted, sorted->end = sorted->start + size; if (sorted->end > s->cap) { + const int oldsize = s->cap * sizeof(*s->entries); s->cap = upb_Log2CeilingSize(sorted->end); - s->entries = realloc(s->entries, s->cap * sizeof(*s->entries)); + const int newsize = s->cap * sizeof(*s->entries); + s->entries = upb_grealloc(s->entries, oldsize, newsize); if (!s->entries) return false; } @@ -6232,8 +6674,8 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type, static int _upb_mapsorter_cmpext(const void* _a, const void* _b) { const upb_Message_Extension* const* a = _a; const upb_Message_Extension* const* b = _b; - uint32_t a_num = (*a)->ext->field.number; - uint32_t b_num = (*b)->ext->field.number; + uint32_t a_num = upb_MiniTableExtension_Number((*a)->ext); + uint32_t b_num = upb_MiniTableExtension_Number((*b)->ext); assert(a_num != b_num); return a_num < b_num ? -1 : 1; } @@ -6253,74 +6695,39 @@ bool _upb_mapsorter_pushexts(_upb_mapsorter* s, } -#include +#include +#include +#include // Must be last. -const float kUpb_FltInfinity = INFINITY; -const double kUpb_Infinity = INFINITY; -const double kUpb_NaN = NAN; +static const size_t message_overhead = sizeof(upb_Message_InternalData); -static const size_t overhead = sizeof(upb_Message_InternalData); +upb_Message* upb_Message_New(const upb_MiniTable* m, upb_Arena* arena) { + return _upb_Message_New(m, arena); +} -upb_Message* upb_Message_New(const upb_MiniTable* mini_table, - upb_Arena* arena) { - return _upb_Message_New(mini_table, arena); +bool UPB_PRIVATE(_upb_Message_AddUnknown)(upb_Message* msg, const char* data, + size_t len, upb_Arena* arena) { + if (!UPB_PRIVATE(_upb_Message_Realloc)(msg, len, arena)) return false; + upb_Message_Internal* in = upb_Message_Getinternal(msg); + memcpy(UPB_PTR_AT(in->internal, in->internal->unknown_end, char), data, len); + in->internal->unknown_end += len; + return true; } -static bool realloc_internal(upb_Message* msg, size_t need, upb_Arena* arena) { - upb_Message_Internal* in = upb_Message_Getinternal(msg); - if (!in->internal) { - /* No internal data, allocate from scratch. */ - size_t size = UPB_MAX(128, upb_Log2CeilingSize(need + overhead)); - upb_Message_InternalData* internal = upb_Arena_Malloc(arena, size); - if (!internal) return false; - internal->size = size; - internal->unknown_end = overhead; - internal->ext_begin = size; - in->internal = internal; - } else if (in->internal->ext_begin - in->internal->unknown_end < need) { - /* Internal data is too small, reallocate. */ - size_t new_size = upb_Log2CeilingSize(in->internal->size + need); - size_t ext_bytes = in->internal->size - in->internal->ext_begin; - size_t new_ext_begin = new_size - ext_bytes; - upb_Message_InternalData* internal = - upb_Arena_Realloc(arena, in->internal, in->internal->size, new_size); - if (!internal) return false; - if (ext_bytes) { - /* Need to move extension data to the end. */ - char* ptr = (char*)internal; - memmove(ptr + new_ext_begin, ptr + internal->ext_begin, ext_bytes); - } - internal->ext_begin = new_ext_begin; - internal->size = new_size; - in->internal = internal; - } - UPB_ASSERT(in->internal->ext_begin - in->internal->unknown_end >= need); - return true; -} - -bool _upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len, - upb_Arena* arena) { - if (!realloc_internal(msg, len, arena)) return false; - upb_Message_Internal* in = upb_Message_Getinternal(msg); - memcpy(UPB_PTR_AT(in->internal, in->internal->unknown_end, char), data, len); - in->internal->unknown_end += len; - return true; -} - -void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) { +void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) { upb_Message_Internal* in = upb_Message_Getinternal(msg); if (in->internal) { - in->internal->unknown_end = overhead; + in->internal->unknown_end = message_overhead; } } const char* upb_Message_GetUnknown(const upb_Message* msg, size_t* len) { const upb_Message_Internal* in = upb_Message_Getinternal(msg); if (in->internal) { - *len = in->internal->unknown_end - overhead; + *len = in->internal->unknown_end - message_overhead; return (char*)(in->internal + 1); } else { *len = 0; @@ -6346,50 +6753,6 @@ void upb_Message_DeleteUnknown(upb_Message* msg, const char* data, size_t len) { in->internal->unknown_end -= len; } -const upb_Message_Extension* _upb_Message_Getexts(const upb_Message* msg, - size_t* count) { - const upb_Message_Internal* in = upb_Message_Getinternal(msg); - if (in->internal) { - *count = (in->internal->size - in->internal->ext_begin) / - sizeof(upb_Message_Extension); - return UPB_PTR_AT(in->internal, in->internal->ext_begin, void); - } else { - *count = 0; - return NULL; - } -} - -const upb_Message_Extension* _upb_Message_Getext( - const upb_Message* msg, const upb_MiniTableExtension* e) { - size_t n; - const upb_Message_Extension* ext = _upb_Message_Getexts(msg, &n); - - /* For now we use linear search exclusively to find extensions. If this - * becomes an issue due to messages with lots of extensions, we can introduce - * a table of some sort. */ - for (size_t i = 0; i < n; i++) { - if (ext[i].ext == e) { - return &ext[i]; - } - } - - return NULL; -} - -upb_Message_Extension* _upb_Message_GetOrCreateExtension( - upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* arena) { - upb_Message_Extension* ext = - (upb_Message_Extension*)_upb_Message_Getext(msg, e); - if (ext) return ext; - if (!realloc_internal(msg, sizeof(upb_Message_Extension), arena)) return NULL; - upb_Message_Internal* in = upb_Message_Getinternal(msg); - in->internal->ext_begin -= sizeof(upb_Message_Extension); - ext = UPB_PTR_AT(in->internal, in->internal->ext_begin, void); - memset(ext, 0, sizeof(upb_Message_Extension)); - ext->ext = e; - return ext; -} - size_t upb_Message_ExtensionCount(const upb_Message* msg) { size_t count; _upb_Message_Getexts(msg, &count); @@ -6397,6 +6760,9 @@ size_t upb_Message_ExtensionCount(const upb_Message* msg) { } +#include +#include + // Must be last. @@ -6422,26 +6788,27 @@ static upb_MiniTableEnum* _upb_MiniTable_AddEnumDataMember(upb_MdEnumDecoder* d, d->enum_table = upb_Arena_Realloc(d->arena, d->enum_table, old_sz, new_sz); upb_MdDecoder_CheckOutOfMemory(&d->base, d->enum_table); } - d->enum_table->data[d->enum_data_count++] = val; + d->enum_table->UPB_PRIVATE(data)[d->enum_data_count++] = val; return d->enum_table; } static void upb_MiniTableEnum_BuildValue(upb_MdEnumDecoder* d, uint32_t val) { upb_MiniTableEnum* table = d->enum_table; d->enum_value_count++; - if (table->value_count || (val > 512 && d->enum_value_count < val / 32)) { - if (table->value_count == 0) { - assert(d->enum_data_count == table->mask_limit / 32); + if (table->UPB_PRIVATE(value_count) || + (val > 512 && d->enum_value_count < val / 32)) { + if (table->UPB_PRIVATE(value_count) == 0) { + UPB_ASSERT(d->enum_data_count == table->UPB_PRIVATE(mask_limit) / 32); } table = _upb_MiniTable_AddEnumDataMember(d, val); - table->value_count++; + table->UPB_PRIVATE(value_count)++; } else { uint32_t new_mask_limit = ((val / 32) + 1) * 32; - while (table->mask_limit < new_mask_limit) { + while (table->UPB_PRIVATE(mask_limit) < new_mask_limit) { table = _upb_MiniTable_AddEnumDataMember(d, 0); - table->mask_limit += 32; + table->UPB_PRIVATE(mask_limit) += 32; } - table->data[val / 32] |= 1ULL << (val % 32); + table->UPB_PRIVATE(data)[val / 32] |= 1ULL << (val % 32); } } @@ -6459,11 +6826,11 @@ static upb_MiniTableEnum* upb_MtDecoder_DoBuildMiniTableEnum( upb_MdDecoder_CheckOutOfMemory(&d->base, d->enum_table); // Guarantee at least 64 bits of mask without checking mask size. - d->enum_table->mask_limit = 64; + d->enum_table->UPB_PRIVATE(mask_limit) = 64; d->enum_table = _upb_MiniTable_AddEnumDataMember(d, 0); d->enum_table = _upb_MiniTable_AddEnumDataMember(d, 0); - d->enum_table->value_count = 0; + d->enum_table->UPB_PRIVATE(value_count) = 0; const char* ptr = data; uint32_t base = 0; @@ -6491,7 +6858,8 @@ static upb_MiniTableEnum* upb_MtDecoder_DoBuildMiniTableEnum( } static upb_MiniTableEnum* upb_MtDecoder_BuildMiniTableEnum( - upb_MdEnumDecoder* const decoder, const char* const data, size_t const len) { + upb_MdEnumDecoder* const decoder, const char* const data, + size_t const len) { if (UPB_SETJMP(decoder->base.err) != 0) return NULL; return upb_MtDecoder_DoBuildMiniTableEnum(decoder, data, len); } @@ -6517,6 +6885,7 @@ upb_MiniTableEnum* upb_MiniDescriptor_BuildEnum(const char* data, size_t len, #include +#include #include @@ -6569,7 +6938,7 @@ enum PresenceClass { }; static bool upb_MtDecoder_FieldIsPackable(upb_MiniTableField* field) { - return (field->mode & kUpb_FieldMode_Array) && + return (field->UPB_PRIVATE(mode) & kUpb_FieldMode_Array) && upb_FieldType_IsPackable(field->UPB_PRIVATE(descriptortype)); } @@ -6586,18 +6955,18 @@ static void upb_MiniTable_SetTypeAndSub(upb_MiniTableField* field, if (is_proto3_enum) { UPB_ASSERT(type == kUpb_FieldType_Enum); type = kUpb_FieldType_Int32; - field->mode |= kUpb_LabelFlags_IsAlternate; + field->UPB_PRIVATE(mode) |= kUpb_LabelFlags_IsAlternate; } else if (type == kUpb_FieldType_String && !(msg_modifiers & kUpb_MessageModifier_ValidateUtf8)) { type = kUpb_FieldType_Bytes; - field->mode |= kUpb_LabelFlags_IsAlternate; + field->UPB_PRIVATE(mode) |= kUpb_LabelFlags_IsAlternate; } field->UPB_PRIVATE(descriptortype) = type; if (upb_MtDecoder_FieldIsPackable(field) && (msg_modifiers & kUpb_MessageModifier_DefaultIsPacked)) { - field->mode |= kUpb_LabelFlags_IsPacked; + field->UPB_PRIVATE(mode) |= kUpb_LabelFlags_IsPacked; } if (type == kUpb_FieldType_Message || type == kUpb_FieldType_Group) { @@ -6664,18 +7033,19 @@ static void upb_MiniTable_SetField(upb_MtDecoder* d, uint8_t ch, int8_t type = _upb_FromBase92(ch); if (ch >= _upb_ToBase92(kUpb_EncodedType_RepeatedBase)) { type -= kUpb_EncodedType_RepeatedBase; - field->mode = kUpb_FieldMode_Array; - field->mode |= pointer_rep << kUpb_FieldRep_Shift; + field->UPB_PRIVATE(mode) = kUpb_FieldMode_Array; + field->UPB_PRIVATE(mode) |= pointer_rep << kUpb_FieldRep_Shift; field->offset = kNoPresence; } else { - field->mode = kUpb_FieldMode_Scalar; + field->UPB_PRIVATE(mode) = kUpb_FieldMode_Scalar; field->offset = kHasbitPresence; if (type == kUpb_EncodedType_Group || type == kUpb_EncodedType_Message) { - field->mode |= pointer_rep << kUpb_FieldRep_Shift; + field->UPB_PRIVATE(mode) |= pointer_rep << kUpb_FieldRep_Shift; } else if ((unsigned long)type >= sizeof(kUpb_EncodedToFieldRep)) { upb_MdDecoder_ErrorJmp(&d->base, "Invalid field type: %d", (int)type); } else { - field->mode |= kUpb_EncodedToFieldRep[type] << kUpb_FieldRep_Shift; + field->UPB_PRIVATE(mode) |= kUpb_EncodedToFieldRep[type] + << kUpb_FieldRep_Shift; } } if ((unsigned long)type >= sizeof(kUpb_EncodedToType)) { @@ -6693,22 +7063,23 @@ static void upb_MtDecoder_ModifyField(upb_MtDecoder* d, if (!upb_MtDecoder_FieldIsPackable(field)) { upb_MdDecoder_ErrorJmp(&d->base, "Cannot flip packed on unpackable field %" PRIu32, - field->number); + upb_MiniTableField_Number(field)); } - field->mode ^= kUpb_LabelFlags_IsPacked; + field->UPB_PRIVATE(mode) ^= kUpb_LabelFlags_IsPacked; } if (field_modifiers & kUpb_EncodedFieldModifier_FlipValidateUtf8) { if (field->UPB_PRIVATE(descriptortype) != kUpb_FieldType_Bytes || - !(field->mode & kUpb_LabelFlags_IsAlternate)) { - upb_MdDecoder_ErrorJmp( - &d->base, - "Cannot flip ValidateUtf8 on field %" PRIu32 ", type=%d, mode=%d", - field->number, (int)field->UPB_PRIVATE(descriptortype), - (int)field->mode); + !(field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsAlternate)) { + upb_MdDecoder_ErrorJmp(&d->base, + "Cannot flip ValidateUtf8 on field %" PRIu32 + ", type=%d, mode=%d", + upb_MiniTableField_Number(field), + (int)field->UPB_PRIVATE(descriptortype), + (int)field->UPB_PRIVATE(mode)); } field->UPB_PRIVATE(descriptortype) = kUpb_FieldType_String; - field->mode &= ~kUpb_LabelFlags_IsAlternate; + field->UPB_PRIVATE(mode) &= ~kUpb_LabelFlags_IsAlternate; } bool singular = field_modifiers & kUpb_EncodedFieldModifier_IsProto3Singular; @@ -6718,12 +7089,12 @@ static void upb_MtDecoder_ModifyField(upb_MtDecoder* d, if ((singular || required) && field->offset != kHasbitPresence) { upb_MdDecoder_ErrorJmp(&d->base, "Invalid modifier(s) for repeated field %" PRIu32, - field->number); + upb_MiniTableField_Number(field)); } if (singular && required) { upb_MdDecoder_ErrorJmp( &d->base, "Field %" PRIu32 " cannot be both singular and required", - field->number); + upb_MiniTableField_Number(field)); } if (singular) field->offset = kNoPresence; @@ -6824,7 +7195,7 @@ static const char* upb_MtDecoder_DecodeOneofField(upb_MtDecoder* d, } // Oneof storage must be large enough to accommodate the largest member. - int rep = f->mode >> kUpb_FieldRep_Shift; + int rep = f->UPB_PRIVATE(mode) >> kUpb_FieldRep_Shift; if (upb_MtDecoder_SizeOfRep(rep, d->platform) > upb_MtDecoder_SizeOfRep(item->rep, d->platform)) { item->rep = rep; @@ -6881,26 +7252,26 @@ static const char* upb_MtDecoder_ParseModifier(upb_MtDecoder* d, static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d, upb_SubCounts sub_counts) { uint32_t total_count = sub_counts.submsg_count + sub_counts.subenum_count; - size_t subs_bytes = sizeof(*d->table->subs) * total_count; + size_t subs_bytes = sizeof(*d->table->UPB_PRIVATE(subs)) * total_count; upb_MiniTableSub* subs = upb_Arena_Malloc(d->arena, subs_bytes); upb_MdDecoder_CheckOutOfMemory(&d->base, subs); uint32_t i = 0; for (; i < sub_counts.submsg_count; i++) { - subs[i].submsg = &_kUpb_MiniTable_Empty; + subs[i].UPB_PRIVATE(submsg) = UPB_PRIVATE(_upb_MiniTable_Empty)(); } if (sub_counts.subenum_count) { upb_MiniTableField* f = d->fields; - upb_MiniTableField* end_f = f + d->table->field_count; + upb_MiniTableField* end_f = f + d->table->UPB_PRIVATE(field_count); for (; f < end_f; f++) { if (f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum) { f->UPB_PRIVATE(submsg_index) += sub_counts.submsg_count; } } for (; i < sub_counts.submsg_count + sub_counts.subenum_count; i++) { - subs[i].subenum = NULL; + subs[i].UPB_PRIVATE(subenum) = NULL; } } - d->table->subs = subs; + d->table->UPB_PRIVATE(subs) = subs; } static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, @@ -6924,14 +7295,14 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, upb_MiniTableField* field = fields; *field_count += 1; fields = (char*)fields + field_size; - field->number = ++last_field_number; + field->UPB_PRIVATE(number) = ++last_field_number; last_field = field; upb_MiniTable_SetField(d, ch, field, msg_modifiers, sub_counts); } else if (kUpb_EncodedValue_MinModifier <= ch && ch <= kUpb_EncodedValue_MaxModifier) { ptr = upb_MtDecoder_ParseModifier(d, ptr, ch, last_field, &msg_modifiers); if (msg_modifiers & kUpb_MessageModifier_IsExtendable) { - d->table->ext |= kUpb_ExtMode_Extendable; + d->table->UPB_PRIVATE(ext) |= kUpb_ExtMode_Extendable; } } else if (ch == kUpb_EncodedValue_End) { if (!d->table) { @@ -6941,7 +7312,7 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, } else if (kUpb_EncodedValue_MinSkip <= ch && ch <= kUpb_EncodedValue_MaxSkip) { if (need_dense_below) { - d->table->dense_below = d->table->field_count; + d->table->UPB_PRIVATE(dense_below) = d->table->UPB_PRIVATE(field_count); need_dense_below = false; } uint32_t skip; @@ -6956,7 +7327,7 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, } if (need_dense_below) { - d->table->dense_below = d->table->field_count; + d->table->UPB_PRIVATE(dense_below) = d->table->UPB_PRIVATE(field_count); } return ptr; @@ -6970,14 +7341,14 @@ static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data, upb_MdDecoder_CheckOutOfMemory(&d->base, d->fields); upb_SubCounts sub_counts = {0, 0}; - d->table->field_count = 0; - d->table->fields = d->fields; + d->table->UPB_PRIVATE(field_count) = 0; + d->table->UPB_PRIVATE(fields) = d->fields; upb_MtDecoder_Parse(d, data, len, d->fields, sizeof(*d->fields), - &d->table->field_count, &sub_counts); + &d->table->UPB_PRIVATE(field_count), &sub_counts); upb_Arena_ShrinkLast(d->arena, d->fields, sizeof(*d->fields) * len, - sizeof(*d->fields) * d->table->field_count); - d->table->fields = d->fields; + sizeof(*d->fields) * d->table->UPB_PRIVATE(field_count)); + d->table->UPB_PRIVATE(fields) = d->fields; upb_MtDecoder_AllocateSubs(d, sub_counts); } @@ -6997,19 +7368,19 @@ int upb_MtDecoder_CompareFields(const void* _a, const void* _b) { #define UPB_COMBINE(rep, ty, idx) (((rep << type_bits) | ty) << idx_bits) | idx uint32_t a_packed = UPB_COMBINE(a->rep, a->type, a->field_index); uint32_t b_packed = UPB_COMBINE(b->rep, b->type, b->field_index); - assert(a_packed != b_packed); + UPB_ASSERT(a_packed != b_packed); #undef UPB_COMBINE return a_packed < b_packed ? -1 : 1; } static bool upb_MtDecoder_SortLayoutItems(upb_MtDecoder* d) { // Add items for all non-oneof fields (oneofs were already added). - int n = d->table->field_count; + int n = d->table->UPB_PRIVATE(field_count); for (int i = 0; i < n; i++) { upb_MiniTableField* f = &d->fields[i]; if (f->offset >= kOneofBase) continue; upb_LayoutItem item = {.field_index = i, - .rep = f->mode >> kUpb_FieldRep_Shift, + .rep = f->UPB_PRIVATE(mode) >> kUpb_FieldRep_Shift, .type = kUpb_LayoutItemType_Field}; upb_MtDecoder_PushItem(d, item); } @@ -7028,46 +7399,49 @@ static size_t upb_MiniTable_DivideRoundUp(size_t n, size_t d) { static void upb_MtDecoder_AssignHasbits(upb_MtDecoder* d) { upb_MiniTable* ret = d->table; - int n = ret->field_count; + int n = ret->UPB_PRIVATE(field_count); int last_hasbit = 0; // 0 cannot be used. // First assign required fields, which must have the lowest hasbits. for (int i = 0; i < n; i++) { - upb_MiniTableField* field = (upb_MiniTableField*)&ret->fields[i]; + upb_MiniTableField* field = + (upb_MiniTableField*)&ret->UPB_PRIVATE(fields)[i]; if (field->offset == kRequiredPresence) { field->presence = ++last_hasbit; } else if (field->offset == kNoPresence) { field->presence = 0; } } - ret->required_count = last_hasbit; - - if (ret->required_count > 63) { + if (last_hasbit > 63) { upb_MdDecoder_ErrorJmp(&d->base, "Too many required fields"); } + ret->UPB_PRIVATE(required_count) = last_hasbit; + // Next assign non-required hasbit fields. for (int i = 0; i < n; i++) { - upb_MiniTableField* field = (upb_MiniTableField*)&ret->fields[i]; + upb_MiniTableField* field = + (upb_MiniTableField*)&ret->UPB_PRIVATE(fields)[i]; if (field->offset == kHasbitPresence) { field->presence = ++last_hasbit; } } - ret->size = last_hasbit ? upb_MiniTable_DivideRoundUp(last_hasbit + 1, 8) : 0; + ret->UPB_PRIVATE(size) = + last_hasbit ? upb_MiniTable_DivideRoundUp(last_hasbit + 1, 8) : 0; } size_t upb_MtDecoder_Place(upb_MtDecoder* d, upb_FieldRep rep) { size_t size = upb_MtDecoder_SizeOfRep(rep, d->platform); size_t align = upb_MtDecoder_AlignOfRep(rep, d->platform); - size_t ret = UPB_ALIGN_UP(d->table->size, align); + size_t ret = UPB_ALIGN_UP(d->table->UPB_PRIVATE(size), align); static const size_t max = UINT16_MAX; size_t new_size = ret + size; if (new_size > max) { upb_MdDecoder_ErrorJmp( &d->base, "Message size exceeded maximum size of %zu bytes", max); } - d->table->size = new_size; + d->table->UPB_PRIVATE(size) = new_size; return ret; } @@ -7087,7 +7461,7 @@ static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) { while (true) { f->presence = ~item->offset; if (f->offset == kUpb_LayoutItem_IndexSentinel) break; - UPB_ASSERT(f->offset - kOneofBase < d->table->field_count); + UPB_ASSERT(f->offset - kOneofBase < d->table->UPB_PRIVATE(field_count)); f = &d->fields[f->offset - kOneofBase]; } } @@ -7117,20 +7491,21 @@ static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) { // // On 32-bit we could potentially make this smaller, but there is no // compelling reason to optimize this right now. - d->table->size = UPB_ALIGN_UP(d->table->size, 8); + d->table->UPB_PRIVATE(size) = UPB_ALIGN_UP(d->table->UPB_PRIVATE(size), 8); } static void upb_MtDecoder_ValidateEntryField(upb_MtDecoder* d, const upb_MiniTableField* f, uint32_t expected_num) { const char* name = expected_num == 1 ? "key" : "val"; - if (f->number != expected_num) { + const uint32_t f_number = upb_MiniTableField_Number(f); + if (f_number != expected_num) { upb_MdDecoder_ErrorJmp(&d->base, "map %s did not have expected number (%d vs %d)", - name, expected_num, (int)f->number); + name, expected_num, f_number); } - if (upb_IsRepeatedOrMap(f)) { + if (!upb_MiniTableField_IsScalar(f)) { upb_MdDecoder_ErrorJmp( &d->base, "map %s cannot be repeated or map, or be in oneof", name); } @@ -7155,9 +7530,9 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data, upb_MtDecoder_ParseMessage(d, data, len); upb_MtDecoder_AssignHasbits(d); - if (UPB_UNLIKELY(d->table->field_count != 2)) { + if (UPB_UNLIKELY(d->table->UPB_PRIVATE(field_count) != 2)) { upb_MdDecoder_ErrorJmp(&d->base, "%hu fields in map", - d->table->field_count); + d->table->UPB_PRIVATE(field_count)); UPB_UNREACHABLE(); } @@ -7168,8 +7543,8 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data, } } - upb_MtDecoder_ValidateEntryField(d, &d->table->fields[0], 1); - upb_MtDecoder_ValidateEntryField(d, &d->table->fields[1], 2); + upb_MtDecoder_ValidateEntryField(d, &d->table->UPB_PRIVATE(fields)[0], 1); + upb_MtDecoder_ValidateEntryField(d, &d->table->UPB_PRIVATE(fields)[1], 2); // Map entries have a pre-determined layout, regardless of types. // NOTE: sync with mini_table/message_internal.h. @@ -7177,11 +7552,12 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data, const size_t hasbit_size = 8; d->fields[0].offset = hasbit_size; d->fields[1].offset = hasbit_size + kv_size; - d->table->size = UPB_ALIGN_UP(hasbit_size + kv_size + kv_size, 8); + d->table->UPB_PRIVATE(size) = + UPB_ALIGN_UP(hasbit_size + kv_size + kv_size, 8); // Map entries have a special bit set to signal it's a map entry, used in // upb_MiniTable_SetSubMessage() below. - d->table->ext |= kUpb_ExtMode_IsMapEntry; + d->table->UPB_PRIVATE(ext) |= kUpb_ExtMode_IsMapEntry; } static void upb_MtDecoder_ParseMessageSet(upb_MtDecoder* d, const char* data, @@ -7192,12 +7568,12 @@ static void upb_MtDecoder_ParseMessageSet(upb_MtDecoder* d, const char* data, } upb_MiniTable* ret = d->table; - ret->size = 0; - ret->field_count = 0; - ret->ext = kUpb_ExtMode_IsMessageSet; - ret->dense_below = 0; - ret->table_mask = -1; - ret->required_count = 0; + ret->UPB_PRIVATE(size) = 0; + ret->UPB_PRIVATE(field_count) = 0; + ret->UPB_PRIVATE(ext) = kUpb_ExtMode_IsMessageSet; + ret->UPB_PRIVATE(dense_below) = 0; + ret->UPB_PRIVATE(table_mask) = -1; + ret->UPB_PRIVATE(required_count) = 0; } static upb_MiniTable* upb_MtDecoder_DoBuildMiniTableWithBuf( @@ -7205,12 +7581,12 @@ static upb_MiniTable* upb_MtDecoder_DoBuildMiniTableWithBuf( size_t* buf_size) { upb_MdDecoder_CheckOutOfMemory(&decoder->base, decoder->table); - decoder->table->size = 0; - decoder->table->field_count = 0; - decoder->table->ext = kUpb_ExtMode_NonExtendable; - decoder->table->dense_below = 0; - decoder->table->table_mask = -1; - decoder->table->required_count = 0; + decoder->table->UPB_PRIVATE(size) = 0; + decoder->table->UPB_PRIVATE(field_count) = 0; + decoder->table->UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable; + decoder->table->UPB_PRIVATE(dense_below) = 0; + decoder->table->UPB_PRIVATE(table_mask) = -1; + decoder->table->UPB_PRIVATE(required_count) = 0; // Strip off and verify the version tag. if (!len--) goto done; @@ -7297,22 +7673,22 @@ static const char* upb_MtDecoder_DoBuildMiniTableExtension( &count, &sub_counts); if (!ret || count != 1) return NULL; - upb_MiniTableField* f = &ext->field; + upb_MiniTableField* f = &ext->UPB_PRIVATE(field); - f->mode |= kUpb_LabelFlags_IsExtension; + f->UPB_PRIVATE(mode) |= kUpb_LabelFlags_IsExtension; f->offset = 0; f->presence = 0; - if (extendee->ext & kUpb_ExtMode_IsMessageSet) { + if (extendee->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMessageSet) { // Extensions of MessageSet must be messages. - if (!upb_IsSubMessage(f)) return NULL; + if (!upb_MiniTableField_IsSubMessage(f)) return NULL; // Extensions of MessageSet must be non-repeating. - if ((f->mode & kUpb_FieldMode_Mask) == kUpb_FieldMode_Array) return NULL; + if (upb_MiniTableField_IsArray(f)) return NULL; } - ext->extendee = extendee; - ext->sub = sub; + ext->UPB_PRIVATE(extendee) = extendee; + ext->UPB_PRIVATE(sub) = sub; return ret; } @@ -7370,25 +7746,32 @@ upb_MiniTable* _upb_MiniTable_Build(const char* data, size_t len, } +#include +#include + + // Must be last. bool upb_MiniTable_SetSubMessage(upb_MiniTable* table, upb_MiniTableField* field, const upb_MiniTable* sub) { - UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field && - (uintptr_t)field < - (uintptr_t)(table->fields + table->field_count)); + UPB_ASSERT((uintptr_t)table->UPB_PRIVATE(fields) <= (uintptr_t)field && + (uintptr_t)field < (uintptr_t)(table->UPB_PRIVATE(fields) + + table->UPB_PRIVATE(field_count))); UPB_ASSERT(sub); - const bool sub_is_map = sub->ext & kUpb_ExtMode_IsMapEntry; + const bool sub_is_map = sub->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry; switch (field->UPB_PRIVATE(descriptortype)) { case kUpb_FieldType_Message: if (sub_is_map) { - const bool table_is_map = table->ext & kUpb_ExtMode_IsMapEntry; + const bool table_is_map = + table->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry; if (UPB_UNLIKELY(table_is_map)) return false; - field->mode = (field->mode & ~kUpb_FieldMode_Mask) | kUpb_FieldMode_Map; + field->UPB_PRIVATE(mode) = + (field->UPB_PRIVATE(mode) & ~kUpb_FieldMode_Mask) | + kUpb_FieldMode_Map; } break; @@ -7401,24 +7784,24 @@ bool upb_MiniTable_SetSubMessage(upb_MiniTable* table, } upb_MiniTableSub* table_sub = - (void*)&table->subs[field->UPB_PRIVATE(submsg_index)]; + (void*)&table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]; // TODO: Add this assert back once YouTube is updated to not call // this function repeatedly. - // UPB_ASSERT(table_sub->submsg == &_kUpb_MiniTable_Empty); - table_sub->submsg = sub; + // UPB_ASSERT(UPB_PRIVATE(_upb_MiniTable_IsEmpty)(table_sub->submsg)); + *table_sub = upb_MiniTableSub_FromMessage(sub); return true; } bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field, const upb_MiniTableEnum* sub) { - UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field && - (uintptr_t)field < - (uintptr_t)(table->fields + table->field_count)); + UPB_ASSERT((uintptr_t)table->UPB_PRIVATE(fields) <= (uintptr_t)field && + (uintptr_t)field < (uintptr_t)(table->UPB_PRIVATE(fields) + + table->UPB_PRIVATE(field_count))); UPB_ASSERT(sub); upb_MiniTableSub* table_sub = - (void*)&table->subs[field->UPB_PRIVATE(submsg_index)]; - table_sub->subenum = sub; + (void*)&table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]; + *table_sub = upb_MiniTableSub_FromEnum(sub); return true; } @@ -7427,8 +7810,8 @@ uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt, uint32_t msg_count = 0; uint32_t enum_count = 0; - for (int i = 0; i < mt->field_count; i++) { - const upb_MiniTableField* f = &mt->fields[i]; + for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) { + const upb_MiniTableField* f = &mt->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_CType(f) == kUpb_CType_Message) { *subs = f; ++subs; @@ -7436,8 +7819,8 @@ uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt, } } - for (int i = 0; i < mt->field_count; i++) { - const upb_MiniTableField* f = &mt->fields[i]; + for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) { + const upb_MiniTableField* f = &mt->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_CType(f) == kUpb_CType_Enum) { *subs = f; ++subs; @@ -7458,8 +7841,8 @@ bool upb_MiniTable_Link(upb_MiniTable* mt, const upb_MiniTable** sub_tables, uint32_t msg_count = 0; uint32_t enum_count = 0; - for (int i = 0; i < mt->field_count; i++) { - upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i]; + for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) { + upb_MiniTableField* f = (upb_MiniTableField*)&mt->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_CType(f) == kUpb_CType_Message) { const upb_MiniTable* sub = sub_tables[msg_count++]; if (msg_count > sub_table_count) return false; @@ -7469,8 +7852,8 @@ bool upb_MiniTable_Link(upb_MiniTable* mt, const upb_MiniTable** sub_tables, } } - for (int i = 0; i < mt->field_count; i++) { - upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i]; + for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) { + upb_MiniTableField* f = (upb_MiniTableField*)&mt->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_IsClosedEnum(f)) { const upb_MiniTableEnum* sub = sub_enums[enum_count++]; if (enum_count > sub_enum_count) return false; @@ -7814,6 +8197,10 @@ char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr) { } +#include +#include +#include + // Must be last. @@ -7840,7 +8227,7 @@ upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena) { UPB_API bool upb_ExtensionRegistry_Add(upb_ExtensionRegistry* r, const upb_MiniTableExtension* e) { char buf[EXTREG_KEY_SIZE]; - extreg_key(buf, e->extendee, e->field.number); + extreg_key(buf, e->UPB_PRIVATE(extendee), upb_MiniTableExtension_Number(e)); if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, NULL)) return false; return upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE, upb_value_constptr(e), r->arena); @@ -7861,7 +8248,8 @@ failure: for (end = e, e = start; e < end; e++) { const upb_MiniTableExtension* ext = *e; char buf[EXTREG_KEY_SIZE]; - extreg_key(buf, ext->extendee, ext->field.number); + extreg_key(buf, ext->UPB_PRIVATE(extendee), + upb_MiniTableExtension_Number(ext)); upb_strtable_remove2(&r->exts, buf, EXTREG_KEY_SIZE, NULL); } return false; @@ -7881,26 +8269,28 @@ const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup( #include +#include +#include // Must be last. const upb_MiniTableField* upb_MiniTable_FindFieldByNumber( - const upb_MiniTable* t, uint32_t number) { + const upb_MiniTable* m, uint32_t number) { const size_t i = ((size_t)number) - 1; // 0 wraps to SIZE_MAX // Ideal case: index into dense fields - if (i < t->dense_below) { - UPB_ASSERT(t->fields[i].number == number); - return &t->fields[i]; + if (i < m->UPB_PRIVATE(dense_below)) { + UPB_ASSERT(m->UPB_PRIVATE(fields)[i].UPB_PRIVATE(number) == number); + return &m->UPB_PRIVATE(fields)[i]; } // Slow case: binary search - int lo = t->dense_below; - int hi = t->field_count - 1; + int lo = m->UPB_PRIVATE(dense_below); + int hi = m->UPB_PRIVATE(field_count) - 1; while (lo <= hi) { int mid = (lo + hi) / 2; - uint32_t num = t->fields[mid].number; + uint32_t num = m->UPB_PRIVATE(fields)[mid].UPB_PRIVATE(number); if (num < number) { lo = mid + 1; continue; @@ -7909,23 +8299,20 @@ const upb_MiniTableField* upb_MiniTable_FindFieldByNumber( hi = mid - 1; continue; } - return &t->fields[mid]; + return &m->UPB_PRIVATE(fields)[mid]; } return NULL; } -static bool upb_MiniTable_Is_Oneof(const upb_MiniTableField* f) { - return f->presence < 0; -} - const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, const upb_MiniTableField* f) { - if (UPB_UNLIKELY(!upb_MiniTable_Is_Oneof(f))) { + if (UPB_UNLIKELY(!upb_MiniTableField_IsInOneof(f))) { return NULL; } - const upb_MiniTableField* ptr = &m->fields[0]; - const upb_MiniTableField* end = &m->fields[m->field_count]; - while (++ptr < end) { + const upb_MiniTableField* ptr = &m->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* end = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; + for (; ptr < end; ptr++) { if (ptr->presence == (*f).presence) { return ptr; } @@ -7936,7 +8323,8 @@ const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, const upb_MiniTableField** f) { const upb_MiniTableField* ptr = *f; - const upb_MiniTableField* end = &m->fields[m->field_count]; + const upb_MiniTableField* end = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; while (++ptr < end) { if (ptr->presence == (*f)->presence) { *f = ptr; @@ -7947,15 +8335,20 @@ bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, } -const struct upb_MiniTable _kUpb_MiniTable_Empty = { - .subs = NULL, - .fields = NULL, - .size = 0, - .field_count = 0, - .ext = kUpb_ExtMode_NonExtendable, - .dense_below = 0, - .table_mask = -1, - .required_count = 0, +#include + +// Must be last. + +// A MiniTable for an empty message, used for unlinked sub-messages. +const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty) = { + .UPB_PRIVATE(subs) = NULL, + .UPB_PRIVATE(fields) = NULL, + .UPB_PRIVATE(size) = 0, + .UPB_PRIVATE(field_count) = 0, + .UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable, + .UPB_PRIVATE(dense_below) = 0, + .UPB_PRIVATE(table_mask) = -1, + .UPB_PRIVATE(required_count) = 0, }; @@ -7968,6 +8361,7 @@ struct upb_DefPool { upb_strtable files; // file_name -> (upb_FileDef*) upb_inttable exts; // (upb_MiniTableExtension*) -> (upb_FieldDef*) upb_ExtensionRegistry* extreg; + const UPB_DESC(FeatureSetDefaults) * feature_set_defaults; upb_MiniTablePlatform platform; void* scratch_data; size_t scratch_size; @@ -7980,6 +8374,8 @@ void upb_DefPool_Free(upb_DefPool* s) { upb_gfree(s); } +static const char serialized_defaults[] = UPB_INTERNAL_UPB_EDITION_DEFAULTS; + upb_DefPool* upb_DefPool_New(void) { upb_DefPool* s = upb_gmalloc(sizeof(*s)); if (!s) return NULL; @@ -8000,6 +8396,14 @@ upb_DefPool* upb_DefPool_New(void) { s->platform = kUpb_MiniTablePlatform_Native; + upb_Status status; + if (!upb_DefPool_SetFeatureSetDefaults( + s, serialized_defaults, sizeof(serialized_defaults) - 1, &status)) { + goto err; + } + + if (!s->feature_set_defaults) goto err; + return s; err: @@ -8007,6 +8411,63 @@ err: return NULL; } +const UPB_DESC(FeatureSetDefaults) * + upb_DefPool_FeatureSetDefaults(const upb_DefPool* s) { + return s->feature_set_defaults; +} + +bool upb_DefPool_SetFeatureSetDefaults(upb_DefPool* s, + const char* serialized_defaults, + size_t serialized_len, + upb_Status* status) { + const UPB_DESC(FeatureSetDefaults)* defaults = UPB_DESC( + FeatureSetDefaults_parse)(serialized_defaults, serialized_len, s->arena); + if (!defaults) { + upb_Status_SetErrorFormat(status, "Failed to parse defaults"); + return false; + } + if (upb_strtable_count(&s->files) > 0) { + upb_Status_SetErrorFormat(status, + "Feature set defaults can't be changed once the " + "pool has started building"); + return false; + } + int min_edition = UPB_DESC(FeatureSetDefaults_minimum_edition(defaults)); + int max_edition = UPB_DESC(FeatureSetDefaults_maximum_edition(defaults)); + if (min_edition > max_edition) { + upb_Status_SetErrorFormat(status, "Invalid edition range %s to %s", + upb_FileDef_EditionName(min_edition), + upb_FileDef_EditionName(max_edition)); + return false; + } + size_t size; + const UPB_DESC( + FeatureSetDefaults_FeatureSetEditionDefault)* const* default_list = + UPB_DESC(FeatureSetDefaults_defaults(defaults, &size)); + int prev_edition = UPB_DESC(EDITION_UNKNOWN); + for (size_t i = 0; i < size; ++i) { + int edition = UPB_DESC( + FeatureSetDefaults_FeatureSetEditionDefault_edition(default_list[i])); + if (edition == UPB_DESC(EDITION_UNKNOWN)) { + upb_Status_SetErrorFormat(status, "Invalid edition UNKNOWN specified"); + return false; + } + if (edition <= prev_edition) { + upb_Status_SetErrorFormat(status, + "Feature set defaults are not strictly " + "increasing, %s is greater than or equal to %s", + upb_FileDef_EditionName(prev_edition), + upb_FileDef_EditionName(edition)); + return false; + } + prev_edition = edition; + } + + // Copy the defaults into the pool. + s->feature_set_defaults = defaults; + return true; +} + bool _upb_DefPool_InsertExt(upb_DefPool* s, const upb_MiniTableExtension* ext, const upb_FieldDef* f) { return upb_inttable_insert(&s->exts, (uintptr_t)ext, upb_value_constptr(f), @@ -8220,7 +8681,11 @@ static const upb_FileDef* upb_DefBuilder_AddFileToPool( remove_filedef(s, builder->file); builder->file = NULL; } - } else if (!builder->arena || !builder->tmp_arena) { + } else if (!builder->arena || !builder->tmp_arena || + !upb_strtable_init(&builder->feature_cache, 16, + builder->tmp_arena) || + !(builder->legacy_features = + UPB_DESC(FeatureSet_new)(builder->tmp_arena))) { _upb_DefBuilder_OomErr(builder); } else { _upb_FileDef_Create(builder, file_proto); @@ -8253,6 +8718,8 @@ static const upb_FileDef* _upb_DefPool_AddFile( upb_DefBuilder ctx = { .symtab = s, + .tmp_buf = NULL, + .tmp_buf_size = 0, .layout = layout, .platform = s->platform, .msg_count = 0, @@ -8368,7 +8835,7 @@ const upb_FieldDef** upb_DefPool_GetAllExtensions(const upb_DefPool* s, const upb_FieldDef* f = upb_value_getconstptr(val); if (upb_FieldDef_ContainingType(f) == m) n++; } - const upb_FieldDef** exts = malloc(n * sizeof(*exts)); + const upb_FieldDef** exts = upb_gmalloc(n * sizeof(*exts)); iter = UPB_INTTABLE_BEGIN; size_t i = 0; while (upb_inttable_next(&s->exts, &key, &val, &iter)) { @@ -8431,11 +8898,16 @@ bool _upb_DescState_Grow(upb_DescState* d, upb_Arena* a) { } +#include +#include +#include + // Must be last. struct upb_EnumDef { - const UPB_DESC(EnumOptions) * opts; + const UPB_DESC(EnumOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; const upb_MiniTableEnum* layout; // Only for proto2. const upb_FileDef* file; const upb_MessageDef* containing_type; // Could be merged with "file". @@ -8449,8 +8921,10 @@ struct upb_EnumDef { int res_range_count; int res_name_count; int32_t defaultval; - bool is_closed; bool is_sorted; // Whether all of the values are defined in ascending order. +#if UINTPTR_MAX == 0xffffffff + uint32_t padding; // Increase size to a multiple of 8. +#endif }; upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i) { @@ -8483,6 +8957,11 @@ bool upb_EnumDef_HasOptions(const upb_EnumDef* e) { return e->opts != (void*)kUpbDefOptDefault; } +const UPB_DESC(FeatureSet) * + upb_EnumDef_ResolvedFeatures(const upb_EnumDef* e) { + return e->resolved_features; +} + const char* upb_EnumDef_FullName(const upb_EnumDef* e) { return e->full_name; } const char* upb_EnumDef_Name(const upb_EnumDef* e) { @@ -8552,7 +9031,11 @@ const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i) { return _upb_EnumValueDef_At(e->values, i); } -bool upb_EnumDef_IsClosed(const upb_EnumDef* e) { return e->is_closed; } +bool upb_EnumDef_IsClosed(const upb_EnumDef* e) { + if (UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3) return false; + return UPB_DESC(FeatureSet_enum_type)(e->resolved_features) == + UPB_DESC(FeatureSet_CLOSED); +} bool upb_EnumDef_MiniDescriptorEncode(const upb_EnumDef* e, upb_Arena* a, upb_StringView* out) { @@ -8621,6 +9104,7 @@ static upb_StringView* _upb_EnumReservedNames_New( static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, const UPB_DESC(EnumDescriptorProto) * enum_proto, + const UPB_DESC(FeatureSet*) parent_features, upb_EnumDef* e) { const UPB_DESC(EnumValueDescriptorProto)* const* values; const UPB_DESC(EnumDescriptorProto_EnumReservedRange)* const* res_ranges; @@ -8628,6 +9112,10 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, upb_StringView name; size_t n_value, n_res_range, n_res_name; + UPB_DEF_SET_OPTIONS(e->opts, EnumDescriptorProto, EnumOptions, enum_proto); + e->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, UPB_DESC(EnumOptions_features)(e->opts)); + // Must happen before _upb_DefBuilder_Add() e->file = _upb_DefBuilder_File(ctx); @@ -8637,9 +9125,6 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, _upb_DefBuilder_Add(ctx, e->full_name, _upb_DefType_Pack(e, UPB_DEFTYPE_ENUM)); - e->is_closed = (!UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3) && - (upb_FileDef_Syntax(e->file) == kUpb_Syntax_Proto2); - values = UPB_DESC(EnumDescriptorProto_value)(enum_proto, &n_value); bool ok = upb_strtable_init(&e->ntoi, n_value, ctx->arena); @@ -8650,8 +9135,8 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, e->defaultval = 0; e->value_count = n_value; - e->values = - _upb_EnumValueDefs_New(ctx, prefix, n_value, values, e, &e->is_sorted); + e->values = _upb_EnumValueDefs_New(ctx, prefix, n_value, values, + e->resolved_features, e, &e->is_sorted); if (n_value == 0) { _upb_DefBuilder_Errf(ctx, "enums must contain at least one value (%s)", @@ -8668,14 +9153,11 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, e->res_name_count = n_res_name; e->res_names = _upb_EnumReservedNames_New(ctx, n_res_name, res_names); - UPB_DEF_SET_OPTIONS(e->opts, EnumDescriptorProto, EnumOptions, enum_proto); - upb_inttable_compact(&e->iton, ctx->arena); - if (e->is_closed) { + if (upb_EnumDef_IsClosed(e)) { if (ctx->layout) { - UPB_ASSERT(ctx->enum_count < ctx->layout->enum_count); - e->layout = ctx->layout->enums[ctx->enum_count++]; + e->layout = upb_MiniTableFile_Enum(ctx->layout, ctx->enum_count++); } else { e->layout = create_enumlayout(ctx, e); } @@ -8684,10 +9166,11 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, } } -upb_EnumDef* _upb_EnumDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(EnumDescriptorProto) * const* protos, - const upb_MessageDef* containing_type) { +upb_EnumDef* _upb_EnumDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(EnumDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + const upb_MessageDef* containing_type) { _upb_DefType_CheckPadding(sizeof(upb_EnumDef)); // If a containing type is defined then get the full name from that. @@ -8697,7 +9180,7 @@ upb_EnumDef* _upb_EnumDefs_New( upb_EnumDef* e = _upb_DefBuilder_Alloc(ctx, sizeof(upb_EnumDef) * n); for (int i = 0; i < n; i++) { - create_enumdef(ctx, name, protos[i], &e[i]); + create_enumdef(ctx, name, protos[i], parent_features, &e[i]); e[i].containing_type = containing_type; } return e; @@ -8756,14 +9239,20 @@ upb_EnumReservedRange* _upb_EnumReservedRanges_New( } +#include + // Must be last. struct upb_EnumValueDef { - const UPB_DESC(EnumValueOptions) * opts; + const UPB_DESC(EnumValueOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; const upb_EnumDef* parent; const char* full_name; int32_t number; +#if UINTPTR_MAX == 0xffffffff + uint32_t padding; // Increase size to a multiple of 8. +#endif }; upb_EnumValueDef* _upb_EnumValueDef_At(const upb_EnumValueDef* v, int i) { @@ -8800,6 +9289,11 @@ bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* v) { return v->opts != (void*)kUpbDefOptDefault; } +const UPB_DESC(FeatureSet) * + upb_EnumValueDef_ResolvedFeatures(const upb_EnumValueDef* e) { + return e->resolved_features; +} + const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* v) { return v->parent; } @@ -8820,9 +9314,15 @@ uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v) { } static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix, - const UPB_DESC(EnumValueDescriptorProto) * + const UPB_DESC(EnumValueDescriptorProto*) val_proto, + const UPB_DESC(FeatureSet*) parent_features, upb_EnumDef* e, upb_EnumValueDef* v) { + UPB_DEF_SET_OPTIONS(v->opts, EnumValueDescriptorProto, EnumValueOptions, + val_proto); + v->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, UPB_DESC(EnumValueOptions_features)(v->opts)); + upb_StringView name = UPB_DESC(EnumValueDescriptorProto_name)(val_proto); v->parent = e; // Must happen prior to _upb_DefBuilder_Add() @@ -8831,17 +9331,32 @@ static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix, _upb_DefBuilder_Add(ctx, v->full_name, _upb_DefType_Pack(v, UPB_DEFTYPE_ENUMVAL)); - UPB_DEF_SET_OPTIONS(v->opts, EnumValueDescriptorProto, EnumValueOptions, - val_proto); - bool ok = _upb_EnumDef_Insert(e, v, ctx->arena); if (!ok) _upb_DefBuilder_OomErr(ctx); } +static void _upb_EnumValueDef_CheckZeroValue(upb_DefBuilder* ctx, + const upb_EnumDef* e, + const upb_EnumValueDef* v, int n) { + if (upb_EnumDef_IsClosed(e) || n == 0 || v[0].number == 0) return; + + // When the special UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 is enabled, we have to + // exempt proto2 enums from this check, even when we are treating them as + // open. + if (UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 && + upb_FileDef_Syntax(upb_EnumDef_File(e)) == kUpb_Syntax_Proto2) { + return; + } + + _upb_DefBuilder_Errf(ctx, "for open enums, the first value must be zero (%s)", + upb_EnumDef_FullName(e)); +} + // Allocate and initialize an array of |n| enum value defs owned by |e|. upb_EnumValueDef* _upb_EnumValueDefs_New( upb_DefBuilder* ctx, const char* prefix, int n, - const UPB_DESC(EnumValueDescriptorProto) * const* protos, upb_EnumDef* e, + const UPB_DESC(EnumValueDescriptorProto*) const* protos, + const UPB_DESC(FeatureSet*) parent_features, upb_EnumDef* e, bool* is_sorted) { _upb_DefType_CheckPadding(sizeof(upb_EnumValueDef)); @@ -8851,29 +9366,27 @@ upb_EnumValueDef* _upb_EnumValueDefs_New( *is_sorted = true; uint32_t previous = 0; for (int i = 0; i < n; i++) { - create_enumvaldef(ctx, prefix, protos[i], e, &v[i]); + create_enumvaldef(ctx, prefix, protos[i], parent_features, e, &v[i]); const uint32_t current = v[i].number; if (previous > current) *is_sorted = false; previous = current; } - if (upb_FileDef_Syntax(ctx->file) == kUpb_Syntax_Proto3 && n > 0 && - v[0].number != 0) { - _upb_DefBuilder_Errf(ctx, - "for proto3, the first enum value must be zero (%s)", - upb_EnumDef_FullName(e)); - } + _upb_EnumValueDef_CheckZeroValue(ctx, e, v, n); return v; } +#include + // Must be last. struct upb_ExtensionRange { - const UPB_DESC(ExtensionRangeOptions) * opts; + const UPB_DESC(ExtensionRangeOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; int32_t start; int32_t end; }; @@ -8899,12 +9412,18 @@ int32_t upb_ExtensionRange_End(const upb_ExtensionRange* r) { return r->end; } upb_ExtensionRange* _upb_ExtensionRanges_New( upb_DefBuilder* ctx, int n, - const UPB_DESC(DescriptorProto_ExtensionRange) * const* protos, - const upb_MessageDef* m) { + const UPB_DESC(DescriptorProto_ExtensionRange*) const* protos, + const UPB_DESC(FeatureSet*) parent_features, const upb_MessageDef* m) { upb_ExtensionRange* r = _upb_DefBuilder_Alloc(ctx, sizeof(upb_ExtensionRange) * n); for (int i = 0; i < n; i++) { + UPB_DEF_SET_OPTIONS(r[i].opts, DescriptorProto_ExtensionRange, + ExtensionRangeOptions, protos[i]); + r[i].resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, + UPB_DESC(ExtensionRangeOptions_features)(r[i].opts)); + const int32_t start = UPB_DESC(DescriptorProto_ExtensionRange_start)(protos[i]); const int32_t end = UPB_DESC(DescriptorProto_ExtensionRange_end)(protos[i]); @@ -8924,8 +9443,6 @@ upb_ExtensionRange* _upb_ExtensionRanges_New( r[i].start = start; r[i].end = end; - UPB_DEF_SET_OPTIONS(r[i].opts, DescriptorProto_ExtensionRange, - ExtensionRangeOptions, protos[i]); } return r; @@ -8935,6 +9452,9 @@ upb_ExtensionRange* _upb_ExtensionRanges_New( #include #include #include +#include +#include +#include // Must be last. @@ -8947,7 +9467,8 @@ typedef struct { } str_t; struct upb_FieldDef { - const UPB_DESC(FieldOptions) * opts; + const UPB_DESC(FieldOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; const upb_FileDef* file; const upb_MessageDef* msgdef; const char* full_name; @@ -8977,13 +9498,9 @@ struct upb_FieldDef { bool has_json_name; bool has_presence; bool is_extension; - bool is_packed; bool is_proto3_optional; upb_FieldType type_; upb_Label label_; -#if UINTPTR_MAX == 0xffffffff - uint32_t padding; // Increase size to a multiple of 8. -#endif }; upb_FieldDef* _upb_FieldDef_At(const upb_FieldDef* f, int i) { @@ -8998,50 +9515,39 @@ bool upb_FieldDef_HasOptions(const upb_FieldDef* f) { return f->opts != (void*)kUpbDefOptDefault; } +const UPB_DESC(FeatureSet) * + upb_FieldDef_ResolvedFeatures(const upb_FieldDef* f) { + return f->resolved_features; +} + const char* upb_FieldDef_FullName(const upb_FieldDef* f) { return f->full_name; } upb_CType upb_FieldDef_CType(const upb_FieldDef* f) { - switch (f->type_) { - case kUpb_FieldType_Double: - return kUpb_CType_Double; - case kUpb_FieldType_Float: - return kUpb_CType_Float; - case kUpb_FieldType_Int64: - case kUpb_FieldType_SInt64: - case kUpb_FieldType_SFixed64: - return kUpb_CType_Int64; - case kUpb_FieldType_Int32: - case kUpb_FieldType_SFixed32: - case kUpb_FieldType_SInt32: - return kUpb_CType_Int32; - case kUpb_FieldType_UInt64: - case kUpb_FieldType_Fixed64: - return kUpb_CType_UInt64; - case kUpb_FieldType_UInt32: - case kUpb_FieldType_Fixed32: - return kUpb_CType_UInt32; - case kUpb_FieldType_Enum: - return kUpb_CType_Enum; - case kUpb_FieldType_Bool: - return kUpb_CType_Bool; - case kUpb_FieldType_String: - return kUpb_CType_String; - case kUpb_FieldType_Bytes: - return kUpb_CType_Bytes; - case kUpb_FieldType_Group: - case kUpb_FieldType_Message: - return kUpb_CType_Message; - } - UPB_UNREACHABLE(); + return upb_FieldType_CType(f->type_); } -upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f) { return f->type_; } +upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f) { + // TODO: remove once we can deprecate kUpb_FieldType_Group. + if (f->type_ == kUpb_FieldType_Message && + UPB_DESC(FeatureSet_message_encoding)(f->resolved_features) == + UPB_DESC(FeatureSet_DELIMITED)) { + return kUpb_FieldType_Group; + } + return f->type_; +} uint32_t upb_FieldDef_Index(const upb_FieldDef* f) { return f->index_; } -upb_Label upb_FieldDef_Label(const upb_FieldDef* f) { return f->label_; } +upb_Label upb_FieldDef_Label(const upb_FieldDef* f) { + // TODO: remove once we can deprecate kUpb_Label_Required. + if (UPB_DESC(FeatureSet_field_presence)(f->resolved_features) == + UPB_DESC(FeatureSet_LEGACY_REQUIRED)) { + return kUpb_Label_Required; + } + return f->label_; +} uint32_t upb_FieldDef_Number(const upb_FieldDef* f) { return f->number_; } @@ -9052,7 +9558,9 @@ bool _upb_FieldDef_IsPackable(const upb_FieldDef* f) { } bool upb_FieldDef_IsPacked(const upb_FieldDef* f) { - return _upb_FieldDef_IsPackable(f) && f->is_packed; + return _upb_FieldDef_IsPackable(f) && + UPB_DESC(FeatureSet_repeated_field_encoding(f->resolved_features)) == + UPB_DESC(FeatureSet_PACKED); } const char* upb_FieldDef_Name(const upb_FieldDef* f) { @@ -9143,7 +9651,7 @@ const upb_MiniTableField* upb_FieldDef_MiniTable(const upb_FieldDef* f) { file, f->layout_index); } else { const upb_MiniTable* layout = upb_MessageDef_MiniTable(f->msgdef); - return &layout->fields[f->layout_index]; + return &layout->UPB_PRIVATE(fields)[f->layout_index]; } } @@ -9165,44 +9673,21 @@ bool _upb_FieldDef_IsProto3Optional(const upb_FieldDef* f) { int _upb_FieldDef_LayoutIndex(const upb_FieldDef* f) { return f->layout_index; } -// begin:google_only -// static bool _upb_FieldDef_EnforceUtf8Option(const upb_FieldDef* f) { -// #if defined(UPB_BOOTSTRAP_STAGE0) -// return true; -// #else -// return UPB_DESC(FieldOptions_enforce_utf8)(f->opts); -// #endif -// } -// end:google_only - -// begin:github_only -static bool _upb_FieldDef_EnforceUtf8Option(const upb_FieldDef* f) { - return true; -} -// end:github_only - bool _upb_FieldDef_ValidateUtf8(const upb_FieldDef* f) { if (upb_FieldDef_Type(f) != kUpb_FieldType_String) return false; - return upb_FileDef_Syntax(upb_FieldDef_File(f)) == kUpb_Syntax_Proto3 - ? _upb_FieldDef_EnforceUtf8Option(f) - : false; + return UPB_DESC(FeatureSet_utf8_validation(f->resolved_features)) == + UPB_DESC(FeatureSet_VERIFY); } uint64_t _upb_FieldDef_Modifiers(const upb_FieldDef* f) { uint64_t out = upb_FieldDef_IsPacked(f) ? kUpb_FieldModifier_IsPacked : 0; - switch (f->label_) { - case kUpb_Label_Optional: - if (!upb_FieldDef_HasPresence(f)) { - out |= kUpb_FieldModifier_IsProto3Singular; - } - break; - case kUpb_Label_Repeated: - out |= kUpb_FieldModifier_IsRepeated; - break; - case kUpb_Label_Required: - out |= kUpb_FieldModifier_IsRequired; - break; + if (upb_FieldDef_IsRepeated(f)) { + out |= kUpb_FieldModifier_IsRepeated; + } else if (upb_FieldDef_IsRequired(f)) { + out |= kUpb_FieldModifier_IsRequired; + } else if (!upb_FieldDef_HasPresence(f)) { + out |= kUpb_FieldModifier_IsProto3Singular; } if (_upb_FieldDef_IsClosedEnum(f)) { @@ -9242,7 +9727,8 @@ bool upb_FieldDef_IsRepeated(const upb_FieldDef* f) { } bool upb_FieldDef_IsRequired(const upb_FieldDef* f) { - return upb_FieldDef_Label(f) == kUpb_Label_Required; + return UPB_DESC(FeatureSet_field_presence)(f->resolved_features) == + UPB_DESC(FeatureSet_LEGACY_REQUIRED); } bool upb_FieldDef_IsString(const upb_FieldDef* f) { @@ -9466,19 +9952,63 @@ static void set_default_default(upb_DefBuilder* ctx, upb_FieldDef* f) { } } +static bool _upb_FieldDef_InferLegacyFeatures( + upb_DefBuilder* ctx, upb_FieldDef* f, + const UPB_DESC(FieldDescriptorProto*) proto, + const UPB_DESC(FieldOptions*) options, upb_Syntax syntax, + UPB_DESC(FeatureSet*) features) { + bool ret = false; + + if (UPB_DESC(FieldDescriptorProto_label)(proto) == kUpb_Label_Required) { + if (syntax == kUpb_Syntax_Proto3) { + _upb_DefBuilder_Errf(ctx, "proto3 fields cannot be required (%s)", + f->full_name); + } + int val = UPB_DESC(FeatureSet_LEGACY_REQUIRED); + UPB_DESC(FeatureSet_set_field_presence(features, val)); + ret = true; + } + + if (UPB_DESC(FieldDescriptorProto_type)(proto) == kUpb_FieldType_Group) { + int val = UPB_DESC(FeatureSet_DELIMITED); + UPB_DESC(FeatureSet_set_message_encoding(features, val)); + ret = true; + } + + if (UPB_DESC(FieldOptions_has_packed)(options)) { + int val = UPB_DESC(FieldOptions_packed)(options) + ? UPB_DESC(FeatureSet_PACKED) + : UPB_DESC(FeatureSet_EXPANDED); + UPB_DESC(FeatureSet_set_repeated_field_encoding(features, val)); + ret = true; + } + +// begin:google_only +// #ifndef UPB_BOOTSTRAP_STAGE0 +// if (syntax == kUpb_Syntax_Proto3 && +// UPB_DESC(FieldOptions_has_enforce_utf8)(options) && +// !UPB_DESC(FieldOptions_enforce_utf8)(options)) { +// int val = UPB_DESC(FeatureSet_UNVERIFIED); +// UPB_DESC(FeatureSet_set_utf8_validation(features, val)); +// ret = true; +// } +// #endif +// // clang-format off +// end:google_only + // clang-format on + + return ret; +} + static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix, - const UPB_DESC(FieldDescriptorProto) * + const UPB_DESC(FeatureSet*) parent_features, + const UPB_DESC(FieldDescriptorProto*) field_proto, upb_MessageDef* m, upb_FieldDef* f) { // Must happen before _upb_DefBuilder_Add() f->file = _upb_DefBuilder_File(ctx); - if (!UPB_DESC(FieldDescriptorProto_has_name)(field_proto)) { - _upb_DefBuilder_Errf(ctx, "field has no name"); - } - const upb_StringView name = UPB_DESC(FieldDescriptorProto_name)(field_proto); - f->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name); f->label_ = (int)UPB_DESC(FieldDescriptorProto_label)(field_proto); f->number_ = UPB_DESC(FieldDescriptorProto_number)(field_proto); @@ -9487,6 +10017,48 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix, f->msgdef = m; f->scope.oneof = NULL; + UPB_DEF_SET_OPTIONS(f->opts, FieldDescriptorProto, FieldOptions, field_proto); + + upb_Syntax syntax = upb_FileDef_Syntax(f->file); + const UPB_DESC(FeatureSet*) unresolved_features = + UPB_DESC(FieldOptions_features)(f->opts); + bool implicit = false; + + if (syntax != kUpb_Syntax_Editions) { + upb_Message_Clear(ctx->legacy_features, UPB_DESC_MINITABLE(FeatureSet)); + if (_upb_FieldDef_InferLegacyFeatures(ctx, f, field_proto, f->opts, syntax, + ctx->legacy_features)) { + implicit = true; + unresolved_features = ctx->legacy_features; + } + } + + if (UPB_DESC(FieldDescriptorProto_has_oneof_index)(field_proto)) { + int oneof_index = UPB_DESC(FieldDescriptorProto_oneof_index)(field_proto); + + if (!m) { + _upb_DefBuilder_Errf(ctx, "oneof field (%s) has no containing msg", + f->full_name); + } + + if (oneof_index >= upb_MessageDef_OneofCount(m)) { + _upb_DefBuilder_Errf(ctx, "oneof_index out of range (%s)", f->full_name); + } + + upb_OneofDef* oneof = (upb_OneofDef*)upb_MessageDef_Oneof(m, oneof_index); + f->scope.oneof = oneof; + parent_features = upb_OneofDef_ResolvedFeatures(oneof); + + _upb_OneofDef_Insert(ctx, oneof, f, name.data, name.size); + } + + f->resolved_features = _upb_DefBuilder_DoResolveFeatures( + ctx, parent_features, unresolved_features, implicit); + + if (!UPB_DESC(FieldDescriptorProto_has_name)(field_proto)) { + _upb_DefBuilder_Errf(ctx, "field has no name"); + } + f->has_json_name = UPB_DESC(FieldDescriptorProto_has_json_name)(field_proto); if (f->has_json_name) { const upb_StringView sv = @@ -9542,56 +10114,28 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix, * to the field_proto until later when we can properly resolve it. */ f->sub.unresolved = field_proto; - if (f->label_ == kUpb_Label_Required && - upb_FileDef_Syntax(f->file) == kUpb_Syntax_Proto3) { - _upb_DefBuilder_Errf(ctx, "proto3 fields cannot be required (%s)", - f->full_name); - } - if (UPB_DESC(FieldDescriptorProto_has_oneof_index)(field_proto)) { - int oneof_index = UPB_DESC(FieldDescriptorProto_oneof_index)(field_proto); - if (upb_FieldDef_Label(f) != kUpb_Label_Optional) { _upb_DefBuilder_Errf(ctx, "fields in oneof must have OPTIONAL label (%s)", f->full_name); } - - if (!m) { - _upb_DefBuilder_Errf(ctx, "oneof field (%s) has no containing msg", - f->full_name); - } - - if (oneof_index >= upb_MessageDef_OneofCount(m)) { - _upb_DefBuilder_Errf(ctx, "oneof_index out of range (%s)", f->full_name); - } - - upb_OneofDef* oneof = (upb_OneofDef*)upb_MessageDef_Oneof(m, oneof_index); - f->scope.oneof = oneof; - - _upb_OneofDef_Insert(ctx, oneof, f, name.data, name.size); - } - - UPB_DEF_SET_OPTIONS(f->opts, FieldDescriptorProto, FieldOptions, field_proto); - - if (UPB_DESC(FieldOptions_has_packed)(f->opts)) { - f->is_packed = UPB_DESC(FieldOptions_packed)(f->opts); - } else { - f->is_packed = upb_FileDef_Syntax(f->file) == kUpb_Syntax_Proto3; } f->has_presence = (!upb_FieldDef_IsRepeated(f)) && (f->type_ == kUpb_FieldType_Message || f->type_ == kUpb_FieldType_Group || upb_FieldDef_ContainingOneof(f) || - (upb_FileDef_Syntax(f->file) == kUpb_Syntax_Proto2)); + UPB_DESC(FeatureSet_field_presence)(f->resolved_features) != + UPB_DESC(FeatureSet_IMPLICIT)); } static void _upb_FieldDef_CreateExt(upb_DefBuilder* ctx, const char* prefix, - const UPB_DESC(FieldDescriptorProto) * + const UPB_DESC(FeatureSet*) parent_features, + const UPB_DESC(FieldDescriptorProto*) field_proto, upb_MessageDef* m, upb_FieldDef* f) { f->is_extension = true; - _upb_FieldDef_Create(ctx, prefix, field_proto, m, f); + _upb_FieldDef_Create(ctx, prefix, parent_features, field_proto, m, f); if (UPB_DESC(FieldDescriptorProto_has_oneof_index)(field_proto)) { _upb_DefBuilder_Errf(ctx, "oneof_index provided for extension field (%s)", @@ -9603,16 +10147,19 @@ static void _upb_FieldDef_CreateExt(upb_DefBuilder* ctx, const char* prefix, f->layout_index = ctx->ext_count++; if (ctx->layout) { - UPB_ASSERT(_upb_FieldDef_ExtensionMiniTable(f)->field.number == f->number_); + UPB_ASSERT(upb_MiniTableExtension_Number( + _upb_FieldDef_ExtensionMiniTable(f)) == f->number_); } } static void _upb_FieldDef_CreateNotExt(upb_DefBuilder* ctx, const char* prefix, - const UPB_DESC(FieldDescriptorProto) * + const UPB_DESC(FeatureSet*) + parent_features, + const UPB_DESC(FieldDescriptorProto*) field_proto, upb_MessageDef* m, upb_FieldDef* f) { f->is_extension = false; - _upb_FieldDef_Create(ctx, prefix, field_proto, m, f); + _upb_FieldDef_Create(ctx, prefix, parent_features, field_proto, m, f); if (!UPB_DESC(FieldDescriptorProto_has_oneof_index)(field_proto)) { if (f->is_proto3_optional) { @@ -9626,10 +10173,11 @@ static void _upb_FieldDef_CreateNotExt(upb_DefBuilder* ctx, const char* prefix, _upb_MessageDef_InsertField(ctx, m, f); } -upb_FieldDef* _upb_Extensions_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(FieldDescriptorProto) * const* protos, const char* prefix, - upb_MessageDef* m) { +upb_FieldDef* _upb_Extensions_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(FieldDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + const char* prefix, upb_MessageDef* m) { _upb_DefType_CheckPadding(sizeof(upb_FieldDef)); upb_FieldDef* defs = (upb_FieldDef*)_upb_DefBuilder_Alloc(ctx, sizeof(upb_FieldDef) * n); @@ -9637,17 +10185,19 @@ upb_FieldDef* _upb_Extensions_New( for (int i = 0; i < n; i++) { upb_FieldDef* f = &defs[i]; - _upb_FieldDef_CreateExt(ctx, prefix, protos[i], m, f); + _upb_FieldDef_CreateExt(ctx, prefix, parent_features, protos[i], m, f); f->index_ = i; } return defs; } -upb_FieldDef* _upb_FieldDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(FieldDescriptorProto) * const* protos, const char* prefix, - upb_MessageDef* m, bool* is_sorted) { +upb_FieldDef* _upb_FieldDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(FieldDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + const char* prefix, upb_MessageDef* m, + bool* is_sorted) { _upb_DefType_CheckPadding(sizeof(upb_FieldDef)); upb_FieldDef* defs = (upb_FieldDef*)_upb_DefBuilder_Alloc(ctx, sizeof(upb_FieldDef) * n); @@ -9656,7 +10206,7 @@ upb_FieldDef* _upb_FieldDefs_New( for (int i = 0; i < n; i++) { upb_FieldDef* f = &defs[i]; - _upb_FieldDef_CreateNotExt(ctx, prefix, protos[i], m, f); + _upb_FieldDef_CreateNotExt(ctx, prefix, parent_features, protos[i], m, f); f->index_ = i; if (!ctx->layout) { // Speculate that the def fields are sorted. We will always sort the @@ -9793,7 +10343,7 @@ void _upb_FieldDef_BuildMiniTableExtension(upb_DefBuilder* ctx, const upb_MiniTableExtension* ext = _upb_FieldDef_ExtensionMiniTable(f); if (ctx->layout) { - UPB_ASSERT(upb_FieldDef_Number(f) == ext->field.number); + UPB_ASSERT(upb_FieldDef_Number(f) == upb_MiniTableExtension_Number(ext)); } else { upb_StringView desc; if (!upb_FieldDef_MiniDescriptorEncode(f, ctx->tmp_arena, &desc)) { @@ -9803,9 +10353,11 @@ void _upb_FieldDef_BuildMiniTableExtension(upb_DefBuilder* ctx, upb_MiniTableExtension* mut_ext = (upb_MiniTableExtension*)ext; upb_MiniTableSub sub = {NULL}; if (upb_FieldDef_IsSubMessage(f)) { - sub.submsg = upb_MessageDef_MiniTable(f->sub.msgdef); + const upb_MiniTable* submsg = upb_MessageDef_MiniTable(f->sub.msgdef); + sub = upb_MiniTableSub_FromMessage(submsg); } else if (_upb_FieldDef_IsClosedEnum(f)) { - sub.subenum = _upb_EnumDef_MiniTable(f->sub.enumdef); + const upb_MiniTableEnum* subenum = _upb_EnumDef_MiniTable(f->sub.enumdef); + sub = upb_MiniTableSub_FromEnum(subenum); } bool ok2 = upb_MiniTableExtension_Init(desc.data, desc.size, mut_ext, upb_MessageDef_MiniTable(f->msgdef), @@ -9860,11 +10412,16 @@ void _upb_FieldDef_Resolve(upb_DefBuilder* ctx, const char* prefix, } +#include +#include +#include + // Must be last. struct upb_FileDef { - const UPB_DESC(FileOptions) * opts; + const UPB_DESC(FileOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; const char* name; const char* package; UPB_DESC(Edition) edition; @@ -9890,10 +10447,29 @@ struct upb_FileDef { upb_Syntax syntax; }; +UPB_API const char* upb_FileDef_EditionName(int edition) { + // TODO Synchronize this with descriptor.proto better. + switch (edition) { + case UPB_DESC(EDITION_PROTO2): + return "PROTO2"; + case UPB_DESC(EDITION_PROTO3): + return "PROTO3"; + case UPB_DESC(EDITION_2023): + return "2023"; + default: + return "UNKNOWN"; + } +} + const UPB_DESC(FileOptions) * upb_FileDef_Options(const upb_FileDef* f) { return f->opts; } +const UPB_DESC(FeatureSet) * + upb_FileDef_ResolvedFeatures(const upb_FileDef* f) { + return f->resolved_features; +} + bool upb_FileDef_HasOptions(const upb_FileDef* f) { return f->opts != (void*)kUpbDefOptDefault; } @@ -10010,6 +10586,49 @@ static int count_exts_in_msg(const UPB_DESC(DescriptorProto) * msg_proto) { return ext_count; } +const UPB_DESC(FeatureSet*) + _upb_FileDef_FindEdition(upb_DefBuilder* ctx, int edition) { + const UPB_DESC(FeatureSetDefaults)* defaults = + upb_DefPool_FeatureSetDefaults(ctx->symtab); + + int min = UPB_DESC(FeatureSetDefaults_minimum_edition)(defaults); + int max = UPB_DESC(FeatureSetDefaults_maximum_edition)(defaults); + if (edition < min) { + _upb_DefBuilder_Errf(ctx, + "Edition %s is earlier than the minimum edition %s " + "given in the defaults", + upb_FileDef_EditionName(edition), + upb_FileDef_EditionName(min)); + return NULL; + } + if (edition > max) { + _upb_DefBuilder_Errf(ctx, + "Edition %s is later than the maximum edition %s " + "given in the defaults", + upb_FileDef_EditionName(edition), + upb_FileDef_EditionName(max)); + return NULL; + } + + size_t n; + const UPB_DESC(FeatureSetDefaults_FeatureSetEditionDefault)* const* d = + UPB_DESC(FeatureSetDefaults_defaults)(defaults, &n); + const UPB_DESC(FeatureSet)* ret = NULL; + for (size_t i = 0; i < n; i++) { + if (UPB_DESC(FeatureSetDefaults_FeatureSetEditionDefault_edition)(d[i]) > + edition) { + break; + } + ret = UPB_DESC(FeatureSetDefaults_FeatureSetEditionDefault_features)(d[i]); + } + if (ret == NULL) { + _upb_DefBuilder_Errf(ctx, "No valid default found for edition %s", + upb_FileDef_EditionName(edition)); + return NULL; + } + return ret; +} + // Allocate and initialize one file def, and add it to the context object. void _upb_FileDef_Create(upb_DefBuilder* ctx, const UPB_DESC(FileDescriptorProto) * file_proto) { @@ -10038,11 +10657,12 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx, if (ctx->layout) { // We are using the ext layouts that were passed in. - file->ext_layouts = ctx->layout->exts; - if (ctx->layout->ext_count != file->ext_count) { + file->ext_layouts = ctx->layout->UPB_PRIVATE(exts); + const int mt_ext_count = upb_MiniTableFile_ExtensionCount(ctx->layout); + if (mt_ext_count != file->ext_count) { _upb_DefBuilder_Errf(ctx, "Extension count did not match layout (%d vs %d)", - ctx->layout->ext_count, file->ext_count); + mt_ext_count, file->ext_count); } } else { // We are building ext layouts from scratch. @@ -10078,21 +10698,33 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx, if (streql_view(syntax, "proto2")) { file->syntax = kUpb_Syntax_Proto2; + file->edition = UPB_DESC(EDITION_PROTO2); } else if (streql_view(syntax, "proto3")) { file->syntax = kUpb_Syntax_Proto3; + file->edition = UPB_DESC(EDITION_PROTO3); } else if (streql_view(syntax, "editions")) { file->syntax = kUpb_Syntax_Editions; + file->edition = UPB_DESC(FileDescriptorProto_edition)(file_proto); } else { _upb_DefBuilder_Errf(ctx, "Invalid syntax '" UPB_STRINGVIEW_FORMAT "'", UPB_STRINGVIEW_ARGS(syntax)); } } else { file->syntax = kUpb_Syntax_Proto2; + file->edition = UPB_DESC(EDITION_PROTO2); } // Read options. UPB_DEF_SET_OPTIONS(file->opts, FileDescriptorProto, FileOptions, file_proto); + // Resolve features. + const UPB_DESC(FeatureSet*) edition_defaults = + _upb_FileDef_FindEdition(ctx, file->edition); + const UPB_DESC(FeatureSet*) unresolved = + UPB_DESC(FileOptions_features)(file->opts); + file->resolved_features = + _upb_DefBuilder_ResolveFeatures(ctx, edition_defaults, unresolved); + // Verify dependencies. strs = UPB_DESC(FileDescriptorProto_dependency)(file_proto, &n); file->dep_count = n; @@ -10138,22 +10770,26 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx, // Create enums. enums = UPB_DESC(FileDescriptorProto_enum_type)(file_proto, &n); file->top_lvl_enum_count = n; - file->top_lvl_enums = _upb_EnumDefs_New(ctx, n, enums, NULL); + file->top_lvl_enums = + _upb_EnumDefs_New(ctx, n, enums, file->resolved_features, NULL); // Create extensions. exts = UPB_DESC(FileDescriptorProto_extension)(file_proto, &n); file->top_lvl_ext_count = n; - file->top_lvl_exts = _upb_Extensions_New(ctx, n, exts, file->package, NULL); + file->top_lvl_exts = _upb_Extensions_New( + ctx, n, exts, file->resolved_features, file->package, NULL); // Create messages. msgs = UPB_DESC(FileDescriptorProto_message_type)(file_proto, &n); file->top_lvl_msg_count = n; - file->top_lvl_msgs = _upb_MessageDefs_New(ctx, n, msgs, NULL); + file->top_lvl_msgs = + _upb_MessageDefs_New(ctx, n, msgs, file->resolved_features, NULL); // Create services. services = UPB_DESC(FileDescriptorProto_service)(file_proto, &n); file->service_count = n; - file->services = _upb_ServiceDefs_New(ctx, n, services); + file->services = + _upb_ServiceDefs_New(ctx, n, services, file->resolved_features); // Now that all names are in the table, build layouts and resolve refs. @@ -10291,15 +10927,15 @@ const void* _upb_DefBuilder_ResolveAny(upb_DefBuilder* ctx, if (sym.size == 0) goto notfound; upb_value v; if (sym.data[0] == '.') { - /* Symbols starting with '.' are absolute, so we do a single lookup. - * Slice to omit the leading '.' */ + // Symbols starting with '.' are absolute, so we do a single lookup. + // Slice to omit the leading '.' if (!_upb_DefPool_LookupSym(ctx->symtab, sym.data + 1, sym.size - 1, &v)) { goto notfound; } } else { - /* Remove components from base until we find an entry or run out. */ + // Remove components from base until we find an entry or run out. size_t baselen = base ? strlen(base) : 0; - char* tmp = malloc(sym.size + baselen + 1); + char* tmp = upb_gmalloc(sym.size + baselen + 1); while (1) { char* p = tmp; if (baselen) { @@ -10313,11 +10949,11 @@ const void* _upb_DefBuilder_ResolveAny(upb_DefBuilder* ctx, break; } if (!remove_component(tmp, &baselen)) { - free(tmp); + upb_gfree(tmp); goto notfound; } } - free(tmp); + upb_gfree(tmp); } *type = _upb_DefType_Type(v); @@ -10516,6 +11152,77 @@ void _upb_DefBuilder_CheckIdentSlow(upb_DefBuilder* ctx, upb_StringView name, UPB_ASSERT(false); } +upb_StringView _upb_DefBuilder_MakeKey(upb_DefBuilder* ctx, + const UPB_DESC(FeatureSet*) parent, + upb_StringView key) { + size_t need = key.size + sizeof(void*); + if (ctx->tmp_buf_size < need) { + ctx->tmp_buf_size = UPB_MAX(64, upb_Log2Ceiling(need)); + ctx->tmp_buf = upb_Arena_Malloc(ctx->tmp_arena, ctx->tmp_buf_size); + if (!ctx->tmp_buf) _upb_DefBuilder_OomErr(ctx); + } + + memcpy(ctx->tmp_buf, &parent, sizeof(void*)); + memcpy(ctx->tmp_buf + sizeof(void*), key.data, key.size); + return upb_StringView_FromDataAndSize(ctx->tmp_buf, need); +} + +bool _upb_DefBuilder_GetOrCreateFeatureSet(upb_DefBuilder* ctx, + const UPB_DESC(FeatureSet*) parent, + upb_StringView key, + UPB_DESC(FeatureSet**) set) { + upb_StringView k = _upb_DefBuilder_MakeKey(ctx, parent, key); + upb_value v; + if (upb_strtable_lookup2(&ctx->feature_cache, k.data, k.size, &v)) { + *set = upb_value_getptr(v); + return false; + } + + *set = + upb_Message_DeepClone(parent, UPB_DESC_MINITABLE(FeatureSet), ctx->arena); + if (!*set) _upb_DefBuilder_OomErr(ctx); + + v = upb_value_ptr(*set); + if (!upb_strtable_insert(&ctx->feature_cache, k.data, k.size, v, + ctx->tmp_arena)) { + _upb_DefBuilder_OomErr(ctx); + } + + return true; +} + +const UPB_DESC(FeatureSet*) + _upb_DefBuilder_DoResolveFeatures(upb_DefBuilder* ctx, + const UPB_DESC(FeatureSet*) parent, + const UPB_DESC(FeatureSet*) child, + bool is_implicit) { + assert(parent); + if (!child) return parent; + + if (child && !is_implicit && + upb_FileDef_Syntax(ctx->file) != kUpb_Syntax_Editions) { + _upb_DefBuilder_Errf(ctx, "Features can only be specified for editions"); + } + + UPB_DESC(FeatureSet*) resolved; + size_t child_size; + const char* child_bytes = + UPB_DESC(FeatureSet_serialize)(child, ctx->tmp_arena, &child_size); + if (!child_bytes) _upb_DefBuilder_OomErr(ctx); + + upb_StringView key = upb_StringView_FromDataAndSize(child_bytes, child_size); + if (!_upb_DefBuilder_GetOrCreateFeatureSet(ctx, parent, key, &resolved)) { + return resolved; + } + + upb_DecodeStatus dec_status = + upb_Decode(child_bytes, child_size, resolved, + UPB_DESC_MINITABLE(FeatureSet), NULL, 0, ctx->arena); + if (dec_status != kUpb_DecodeStatus_Ok) _upb_DefBuilder_OomErr(ctx); + + return resolved; +} + #include @@ -10541,6 +11248,7 @@ char* upb_strdup2(const char* s, size_t len, upb_Arena* a) { } +#include #include @@ -10569,9 +11277,7 @@ const upb_FieldDef* upb_Message_WhichOneof(const upb_Message* msg, upb_MessageValue upb_Message_GetFieldByDef(const upb_Message* msg, const upb_FieldDef* f) { upb_MessageValue default_val = upb_FieldDef_Default(f); - upb_MessageValue ret; - _upb_Message_GetField(msg, upb_FieldDef_MiniTable(f), &default_val, &ret); - return ret; + return upb_Message_GetField(msg, upb_FieldDef_MiniTable(f), default_val); } upb_MutableMessageValue upb_Message_Mutable(upb_Message* msg, @@ -10615,7 +11321,7 @@ make: bool upb_Message_SetFieldByDef(upb_Message* msg, const upb_FieldDef* f, upb_MessageValue val, upb_Arena* a) { - return _upb_Message_SetField(msg, upb_FieldDef_MiniTable(f), &val, a); + return upb_Message_SetField(msg, upb_FieldDef_MiniTable(f), val, a); } void upb_Message_ClearFieldByDef(upb_Message* msg, const upb_FieldDef* f) { @@ -10643,7 +11349,7 @@ bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m, if (upb_MiniTableField_HasPresence(field)) { if (!upb_Message_HasFieldByDef(msg, f)) continue; } else { - switch (upb_FieldMode_Get(field)) { + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(field)) { case kUpb_FieldMode_Map: if (!val.map_val || upb_Map_Size(val.map_val) == 0) continue; break; @@ -10651,7 +11357,8 @@ bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m, if (!val.array_val || upb_Array_Size(val.array_val) == 0) continue; break; case kUpb_FieldMode_Scalar: - if (!_upb_MiniTable_ValueIsNonZero(&val, field)) continue; + if (UPB_PRIVATE(_upb_MiniTableField_DataIsZero)(field, &val)) + continue; break; } } @@ -10735,11 +11442,16 @@ bool upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m, } +#include +#include +#include + // Must be last. struct upb_MessageDef { - const UPB_DESC(MessageOptions) * opts; + const UPB_DESC(MessageOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; const upb_MiniTable* layout; const upb_FileDef* file; const upb_MessageDef* containing_type; @@ -10777,6 +11489,9 @@ struct upb_MessageDef { bool in_message_set; bool is_sorted; upb_WellKnown well_known_type; +#if UINTPTR_MAX == 0xffffffff + uint32_t padding; // Increase size to a multiple of 8. +#endif }; static void assign_msg_wellknowntype(upb_MessageDef* m) { @@ -10845,6 +11560,11 @@ bool upb_MessageDef_HasOptions(const upb_MessageDef* m) { return m->opts != (void*)kUpbDefOptDefault; } +const UPB_DESC(FeatureSet) * + upb_MessageDef_ResolvedFeatures(const upb_MessageDef* m) { + return m->resolved_features; +} + const char* upb_MessageDef_FullName(const upb_MessageDef* m) { return m->full_name; } @@ -11108,10 +11828,9 @@ void _upb_MessageDef_InsertField(upb_DefBuilder* ctx, upb_MessageDef* m, _upb_MessageDef_Insert(m, shortname, shortnamelen, field_v, ctx->arena); if (!ok) _upb_DefBuilder_OomErr(ctx); - // TODO: Once editions is supported this should turn into a - // check on LEGACY_BEST_EFFORT if (strcmp(shortname, json_name) != 0 && - upb_FileDef_Syntax(m->file) == kUpb_Syntax_Proto3 && + UPB_DESC(FeatureSet_json_format)(m->resolved_features) == + UPB_DESC(FeatureSet_ALLOW) && upb_strtable_lookup(&m->ntof, json_name, &v)) { _upb_DefBuilder_Errf( ctx, "duplicate json_name for (%s) with original field name (%s)", @@ -11139,9 +11858,8 @@ void _upb_MessageDef_CreateMiniTable(upb_DefBuilder* ctx, upb_MessageDef* m) { if (ctx->layout == NULL) { m->layout = _upb_MessageDef_MakeMiniTable(ctx, m); } else { - UPB_ASSERT(ctx->msg_count < ctx->layout->msg_count); - m->layout = ctx->layout->msgs[ctx->msg_count++]; - UPB_ASSERT(m->field_count == m->layout->field_count); + m->layout = upb_MiniTableFile_Message(ctx->layout, ctx->msg_count++); + UPB_ASSERT(m->field_count == m->layout->UPB_PRIVATE(field_count)); // We don't need the result of this call, but it will assign layout_index // for all the fields in O(n lg n) time. @@ -11177,9 +11895,9 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx, UPB_ASSERT(layout_index < m->field_count); upb_MiniTableField* mt_f = - (upb_MiniTableField*)&m->layout->fields[layout_index]; + (upb_MiniTableField*)&m->layout->UPB_PRIVATE(fields)[layout_index]; if (sub_m) { - if (!mt->subs) { + if (!mt->UPB_PRIVATE(subs)) { _upb_DefBuilder_Errf(ctx, "unexpected submsg for (%s)", m->full_name); } UPB_ASSERT(mt_f); @@ -11199,8 +11917,9 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx, for (int i = 0; i < m->field_count; i++) { const upb_FieldDef* f = upb_MessageDef_Field(m, i); const int layout_index = _upb_FieldDef_LayoutIndex(f); - UPB_ASSERT(layout_index < m->layout->field_count); - const upb_MiniTableField* mt_f = &m->layout->fields[layout_index]; + UPB_ASSERT(layout_index < m->layout->UPB_PRIVATE(field_count)); + const upb_MiniTableField* mt_f = + &m->layout->UPB_PRIVATE(fields)[layout_index]; UPB_ASSERT(upb_FieldDef_Type(f) == upb_MiniTableField_Type(mt_f)); UPB_ASSERT(upb_FieldDef_CType(f) == upb_MiniTableField_CType(mt_f)); UPB_ASSERT(upb_FieldDef_HasPresence(f) == @@ -11228,7 +11947,8 @@ static bool _upb_MessageDef_ValidateUtf8(const upb_MessageDef* m) { static uint64_t _upb_MessageDef_Modifiers(const upb_MessageDef* m) { uint64_t out = 0; - if (upb_FileDef_Syntax(m->file) == kUpb_Syntax_Proto3) { + if (UPB_DESC(FeatureSet_repeated_field_encoding(m->resolved_features)) == + UPB_DESC(FeatureSet_PACKED)) { out |= kUpb_MessageModifier_DefaultIsPacked; } @@ -11342,7 +12062,8 @@ static upb_StringView* _upb_ReservedNames_New(upb_DefBuilder* ctx, int n, } static void create_msgdef(upb_DefBuilder* ctx, const char* prefix, - const UPB_DESC(DescriptorProto) * msg_proto, + const UPB_DESC(DescriptorProto*) msg_proto, + const UPB_DESC(FeatureSet*) parent_features, const upb_MessageDef* containing_type, upb_MessageDef* m) { const UPB_DESC(OneofDescriptorProto)* const* oneofs; @@ -11354,6 +12075,10 @@ static void create_msgdef(upb_DefBuilder* ctx, const char* prefix, size_t n_ext_range, n_res_range, n_res_name; upb_StringView name; + UPB_DEF_SET_OPTIONS(m->opts, DescriptorProto, MessageOptions, msg_proto); + m->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, UPB_DESC(MessageOptions_features)(m->opts)); + // Must happen before _upb_DefBuilder_Add() m->file = _upb_DefBuilder_File(ctx); @@ -11382,14 +12107,12 @@ static void create_msgdef(upb_DefBuilder* ctx, const char* prefix, ok = upb_strtable_init(&m->jtof, n_field, ctx->arena); if (!ok) _upb_DefBuilder_OomErr(ctx); - UPB_DEF_SET_OPTIONS(m->opts, DescriptorProto, MessageOptions, msg_proto); - m->oneof_count = n_oneof; - m->oneofs = _upb_OneofDefs_New(ctx, n_oneof, oneofs, m); + m->oneofs = _upb_OneofDefs_New(ctx, n_oneof, oneofs, m->resolved_features, m); m->field_count = n_field; - m->fields = - _upb_FieldDefs_New(ctx, n_field, fields, m->full_name, m, &m->is_sorted); + m->fields = _upb_FieldDefs_New(ctx, n_field, fields, m->resolved_features, + m->full_name, m, &m->is_sorted); // Message Sets may not contain fields. if (UPB_UNLIKELY(UPB_DESC(MessageOptions_message_set_wire_format)(m->opts))) { @@ -11399,7 +12122,8 @@ static void create_msgdef(upb_DefBuilder* ctx, const char* prefix, } m->ext_range_count = n_ext_range; - m->ext_ranges = _upb_ExtensionRanges_New(ctx, n_ext_range, ext_ranges, m); + m->ext_ranges = _upb_ExtensionRanges_New(ctx, n_ext_range, ext_ranges, + m->resolved_features, m); m->res_range_count = n_res_range; m->res_ranges = @@ -11417,23 +12141,29 @@ static void create_msgdef(upb_DefBuilder* ctx, const char* prefix, const UPB_DESC(EnumDescriptorProto)* const* enums = UPB_DESC(DescriptorProto_enum_type)(msg_proto, &n_enum); m->nested_enum_count = n_enum; - m->nested_enums = _upb_EnumDefs_New(ctx, n_enum, enums, m); + m->nested_enums = + _upb_EnumDefs_New(ctx, n_enum, enums, m->resolved_features, m); const UPB_DESC(FieldDescriptorProto)* const* exts = UPB_DESC(DescriptorProto_extension)(msg_proto, &n_ext); m->nested_ext_count = n_ext; - m->nested_exts = _upb_Extensions_New(ctx, n_ext, exts, m->full_name, m); + m->nested_exts = _upb_Extensions_New(ctx, n_ext, exts, m->resolved_features, + m->full_name, m); const UPB_DESC(DescriptorProto)* const* msgs = UPB_DESC(DescriptorProto_nested_type)(msg_proto, &n_msg); m->nested_msg_count = n_msg; - m->nested_msgs = _upb_MessageDefs_New(ctx, n_msg, msgs, m); + m->nested_msgs = + _upb_MessageDefs_New(ctx, n_msg, msgs, m->resolved_features, m); } // Allocate and initialize an array of |n| message defs. -upb_MessageDef* _upb_MessageDefs_New( - upb_DefBuilder* ctx, int n, const UPB_DESC(DescriptorProto) * const* protos, - const upb_MessageDef* containing_type) { +upb_MessageDef* _upb_MessageDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(DescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) + parent_features, + const upb_MessageDef* containing_type) { _upb_DefType_CheckPadding(sizeof(upb_MessageDef)); const char* name = containing_type ? containing_type->full_name @@ -11441,7 +12171,8 @@ upb_MessageDef* _upb_MessageDefs_New( upb_MessageDef* m = _upb_DefBuilder_Alloc(ctx, sizeof(upb_MessageDef) * n); for (int i = 0; i < n; i++) { - create_msgdef(ctx, name, protos[i], containing_type, &m[i]); + create_msgdef(ctx, name, protos[i], parent_features, containing_type, + &m[i]); } return m; } @@ -11500,7 +12231,8 @@ upb_MessageReservedRange* _upb_MessageReservedRanges_New( // Must be last. struct upb_MethodDef { - const UPB_DESC(MethodOptions) * opts; + const UPB_DESC(MethodOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; upb_ServiceDef* service; const char* full_name; const upb_MessageDef* input_type; @@ -11526,6 +12258,11 @@ bool upb_MethodDef_HasOptions(const upb_MethodDef* m) { return m->opts != (void*)kUpbDefOptDefault; } +const UPB_DESC(FeatureSet) * + upb_MethodDef_ResolvedFeatures(const upb_MethodDef* m) { + return m->resolved_features; +} + const char* upb_MethodDef_FullName(const upb_MethodDef* m) { return m->full_name; } @@ -11553,8 +12290,14 @@ bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m) { } static void create_method(upb_DefBuilder* ctx, - const UPB_DESC(MethodDescriptorProto) * method_proto, + const UPB_DESC(MethodDescriptorProto*) method_proto, + const UPB_DESC(FeatureSet*) parent_features, upb_ServiceDef* s, upb_MethodDef* m) { + UPB_DEF_SET_OPTIONS(m->opts, MethodDescriptorProto, MethodOptions, + method_proto); + m->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, UPB_DESC(MethodOptions_features)(m->opts)); + upb_StringView name = UPB_DESC(MethodDescriptorProto_name)(method_proto); m->service = s; @@ -11572,18 +12315,17 @@ static void create_method(upb_DefBuilder* ctx, ctx, m->full_name, m->full_name, UPB_DESC(MethodDescriptorProto_output_type)(method_proto), UPB_DEFTYPE_MSG); - - UPB_DEF_SET_OPTIONS(m->opts, MethodDescriptorProto, MethodOptions, - method_proto); } // Allocate and initialize an array of |n| method defs belonging to |s|. -upb_MethodDef* _upb_MethodDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(MethodDescriptorProto) * const* protos, upb_ServiceDef* s) { +upb_MethodDef* _upb_MethodDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(MethodDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + upb_ServiceDef* s) { upb_MethodDef* m = _upb_DefBuilder_Alloc(ctx, sizeof(upb_MethodDef) * n); for (int i = 0; i < n; i++) { - create_method(ctx, protos[i], s, &m[i]); + create_method(ctx, protos[i], parent_features, s, &m[i]); m[i].index = i; } return m; @@ -11598,7 +12340,8 @@ upb_MethodDef* _upb_MethodDefs_New( // Must be last. struct upb_OneofDef { - const UPB_DESC(OneofOptions) * opts; + const UPB_DESC(OneofOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; const upb_MessageDef* parent; const char* full_name; int field_count; @@ -11606,9 +12349,6 @@ struct upb_OneofDef { const upb_FieldDef** fields; upb_strtable ntof; // lookup a field by name upb_inttable itof; // lookup a field by number (index) -#if UINTPTR_MAX == 0xffffffff - uint32_t padding; // Increase size to a multiple of 8. -#endif }; upb_OneofDef* _upb_OneofDef_At(const upb_OneofDef* o, int i) { @@ -11623,6 +12363,11 @@ bool upb_OneofDef_HasOptions(const upb_OneofDef* o) { return o->opts != (void*)kUpbDefOptDefault; } +const UPB_DESC(FeatureSet) * + upb_OneofDef_ResolvedFeatures(const upb_OneofDef* o) { + return o->resolved_features; +} + const char* upb_OneofDef_FullName(const upb_OneofDef* o) { return o->full_name; } @@ -11742,9 +12487,15 @@ size_t _upb_OneofDefs_Finalize(upb_DefBuilder* ctx, upb_MessageDef* m) { } static void create_oneofdef(upb_DefBuilder* ctx, upb_MessageDef* m, - const UPB_DESC(OneofDescriptorProto) * oneof_proto, + const UPB_DESC(OneofDescriptorProto*) oneof_proto, + const UPB_DESC(FeatureSet*) parent_features, const upb_OneofDef* _o) { upb_OneofDef* o = (upb_OneofDef*)_o; + + UPB_DEF_SET_OPTIONS(o->opts, OneofDescriptorProto, OneofOptions, oneof_proto); + o->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, UPB_DESC(OneofOptions_features)(o->opts)); + upb_StringView name = UPB_DESC(OneofDescriptorProto_name)(oneof_proto); o->parent = m; @@ -11753,8 +12504,6 @@ static void create_oneofdef(upb_DefBuilder* ctx, upb_MessageDef* m, o->field_count = 0; o->synthetic = false; - UPB_DEF_SET_OPTIONS(o->opts, OneofDescriptorProto, OneofOptions, oneof_proto); - if (upb_MessageDef_FindByNameWithSize(m, name.data, name.size, NULL, NULL)) { _upb_DefBuilder_Errf(ctx, "duplicate oneof name (%s)", o->full_name); } @@ -11771,14 +12520,16 @@ static void create_oneofdef(upb_DefBuilder* ctx, upb_MessageDef* m, } // Allocate and initialize an array of |n| oneof defs. -upb_OneofDef* _upb_OneofDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(OneofDescriptorProto) * const* protos, upb_MessageDef* m) { +upb_OneofDef* _upb_OneofDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(OneofDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + upb_MessageDef* m) { _upb_DefType_CheckPadding(sizeof(upb_OneofDef)); upb_OneofDef* o = _upb_DefBuilder_Alloc(ctx, sizeof(upb_OneofDef) * n); for (int i = 0; i < n; i++) { - create_oneofdef(ctx, m, protos[i], &o[i]); + create_oneofdef(ctx, m, protos[i], parent_features, &o[i]); } return o; } @@ -11788,12 +12539,16 @@ upb_OneofDef* _upb_OneofDefs_New( // Must be last. struct upb_ServiceDef { - const UPB_DESC(ServiceOptions) * opts; + const UPB_DESC(ServiceOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; const upb_FileDef* file; const char* full_name; upb_MethodDef* methods; int method_count; int index; +#if UINTPTR_MAX == 0xffffffff + uint32_t padding; // Increase size to a multiple of 8. +#endif }; upb_ServiceDef* _upb_ServiceDef_At(const upb_ServiceDef* s, int index) { @@ -11809,6 +12564,11 @@ bool upb_ServiceDef_HasOptions(const upb_ServiceDef* s) { return s->opts != (void*)kUpbDefOptDefault; } +const UPB_DESC(FeatureSet) * + upb_ServiceDef_ResolvedFeatures(const upb_ServiceDef* s) { + return s->resolved_features; +} + const char* upb_ServiceDef_FullName(const upb_ServiceDef* s) { return s->full_name; } @@ -11844,37 +12604,40 @@ const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s, } static void create_service(upb_DefBuilder* ctx, - const UPB_DESC(ServiceDescriptorProto) * svc_proto, + const UPB_DESC(ServiceDescriptorProto*) svc_proto, + const UPB_DESC(FeatureSet*) parent_features, upb_ServiceDef* s) { - upb_StringView name; - size_t n; + UPB_DEF_SET_OPTIONS(s->opts, ServiceDescriptorProto, ServiceOptions, + svc_proto); + s->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, UPB_DESC(ServiceOptions_features)(s->opts)); // Must happen before _upb_DefBuilder_Add() s->file = _upb_DefBuilder_File(ctx); - name = UPB_DESC(ServiceDescriptorProto_name)(svc_proto); + upb_StringView name = UPB_DESC(ServiceDescriptorProto_name)(svc_proto); const char* package = _upb_FileDef_RawPackage(s->file); s->full_name = _upb_DefBuilder_MakeFullName(ctx, package, name); _upb_DefBuilder_Add(ctx, s->full_name, _upb_DefType_Pack(s, UPB_DEFTYPE_SERVICE)); + size_t n; const UPB_DESC(MethodDescriptorProto)* const* methods = UPB_DESC(ServiceDescriptorProto_method)(svc_proto, &n); s->method_count = n; - s->methods = _upb_MethodDefs_New(ctx, n, methods, s); - - UPB_DEF_SET_OPTIONS(s->opts, ServiceDescriptorProto, ServiceOptions, - svc_proto); + s->methods = _upb_MethodDefs_New(ctx, n, methods, s->resolved_features, s); } -upb_ServiceDef* _upb_ServiceDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(ServiceDescriptorProto) * const* protos) { +upb_ServiceDef* _upb_ServiceDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(ServiceDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) + parent_features) { _upb_DefType_CheckPadding(sizeof(upb_ServiceDef)); upb_ServiceDef* s = _upb_DefBuilder_Alloc(ctx, sizeof(upb_ServiceDef) * n); for (int i = 0; i < n; i++) { - create_service(ctx, protos[i], &s[i]); + create_service(ctx, protos[i], parent_features, &s[i]); s[i].index = i; } return s; @@ -11929,6 +12692,27 @@ typedef union { uint32_t size; } wireval; +// Ideally these two functions should take the owning MiniTable pointer as a +// first argument, then we could just put them in mini_table/message.h as nice +// clean getters. But we don't have that so instead we gotta write these +// Frankenfunctions that take an array of subtables. +// TODO: Move these to mini_table/ anyway since there are other places +// that could use them. + +// Returns the MiniTable corresponding to a given MiniTableField +// from an array of MiniTableSubs. +static const upb_MiniTable* _upb_MiniTableSubs_MessageByField( + const upb_MiniTableSub* subs, const upb_MiniTableField* field) { + return upb_MiniTableSub_Message(subs[field->UPB_PRIVATE(submsg_index)]); +} + +// Returns the MiniTableEnum corresponding to a given MiniTableField +// from an array of MiniTableSub. +static const upb_MiniTableEnum* _upb_MiniTableSubs_EnumByField( + const upb_MiniTableSub* subs, const upb_MiniTableField* field) { + return upb_MiniTableSub_Enum(subs[field->UPB_PRIVATE(submsg_index)]); +} + static const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr, upb_Message* msg, const upb_MiniTable* layout); @@ -11954,8 +12738,9 @@ static void _upb_Decoder_VerifyUtf8(upb_Decoder* d, const char* buf, int len) { } static bool _upb_Decoder_Reserve(upb_Decoder* d, upb_Array* arr, size_t elem) { - bool need_realloc = arr->capacity - arr->size < elem; - if (need_realloc && !_upb_array_realloc(arr, arr->size + elem, &d->arena)) { + bool need_realloc = arr->UPB_PRIVATE(capacity) - arr->size < elem; + if (need_realloc && + !UPB_PRIVATE(_upb_Array_Realloc)(arr, arr->size + elem, &d->arena)) { _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } return need_realloc; @@ -12064,15 +12849,15 @@ static upb_Message* _upb_Decoder_NewSubMessage(upb_Decoder* d, const upb_MiniTableSub* subs, const upb_MiniTableField* field, upb_TaggedMessagePtr* target) { - const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(subl); upb_Message* msg = _upb_Message_New(subl, &d->arena); if (!msg) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); - // Extensions should not be unlinked. A message extension should not be + // Extensions should not be unlinked. A message extension should not be // registered until its sub-message type is available to be linked. - bool is_empty = subl == &_kUpb_MiniTable_Empty; - bool is_extension = field->mode & kUpb_LabelFlags_IsExtension; + bool is_empty = UPB_PRIVATE(_upb_MiniTable_IsEmpty)(subl); + bool is_extension = field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsExtension; UPB_ASSERT(!(is_empty && is_extension)); if (is_empty && !(d->options & kUpb_DecodeOption_ExperimentalAllowUnlinked)) { @@ -12088,9 +12873,10 @@ static upb_Message* _upb_Decoder_ReuseSubMessage( upb_Decoder* d, const upb_MiniTableSub* subs, const upb_MiniTableField* field, upb_TaggedMessagePtr* target) { upb_TaggedMessagePtr tagged = *target; - const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(subl); - if (!upb_TaggedMessagePtr_IsEmpty(tagged) || subl == &_kUpb_MiniTable_Empty) { + if (!upb_TaggedMessagePtr_IsEmpty(tagged) || + UPB_PRIVATE(_upb_MiniTable_IsEmpty)(subl)) { return _upb_TaggedMessagePtr_GetMessage(tagged); } @@ -12139,7 +12925,7 @@ static const char* _upb_Decoder_DecodeSubMessage( upb_Decoder* d, const char* ptr, upb_Message* submsg, const upb_MiniTableSub* subs, const upb_MiniTableField* field, int size) { int saved_delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, size); - const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(subl); ptr = _upb_Decoder_RecurseSubMessage(d, ptr, submsg, subl, DECODE_NOGROUP); upb_EpsCopyInputStream_PopLimit(&d->input, ptr, saved_delta); @@ -12170,9 +12956,10 @@ UPB_FORCEINLINE static const char* _upb_Decoder_DecodeKnownGroup( upb_Decoder* d, const char* ptr, upb_Message* submsg, const upb_MiniTableSub* subs, const upb_MiniTableField* field) { - const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(subl); - return _upb_Decoder_DecodeGroup(d, ptr, submsg, subl, field->number); + return _upb_Decoder_DecodeGroup(d, ptr, submsg, subl, + field->UPB_PRIVATE(number)); } static char* upb_Decoder_EncodeVarint32(uint32_t val, char* ptr) { @@ -12192,39 +12979,30 @@ static void _upb_Decoder_AddUnknownVarints(upb_Decoder* d, upb_Message* msg, end = upb_Decoder_EncodeVarint32(val1, end); end = upb_Decoder_EncodeVarint32(val2, end); - if (!_upb_Message_AddUnknown(msg, buf, end - buf, &d->arena)) { + if (!UPB_PRIVATE(_upb_Message_AddUnknown)(msg, buf, end - buf, &d->arena)) { _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } } -UPB_NOINLINE -static bool _upb_Decoder_CheckEnumSlow(upb_Decoder* d, const char* ptr, - upb_Message* msg, - const upb_MiniTableEnum* e, - const upb_MiniTableField* field, - uint32_t v) { - if (_upb_MiniTable_CheckEnumValueSlow(e, v)) return true; - - // Unrecognized enum goes into unknown fields. - // For packed fields the tag could be arbitrarily far in the past, so we - // just re-encode the tag and value here. - uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Varint; - upb_Message* unknown_msg = - field->mode & kUpb_LabelFlags_IsExtension ? d->unknown_msg : msg; - _upb_Decoder_AddUnknownVarints(d, unknown_msg, tag, v); - return false; -} - UPB_FORCEINLINE static bool _upb_Decoder_CheckEnum(upb_Decoder* d, const char* ptr, upb_Message* msg, const upb_MiniTableEnum* e, const upb_MiniTableField* field, wireval* val) { - uint32_t v = val->uint32_val; + const uint32_t v = val->uint32_val; + + if (UPB_LIKELY(upb_MiniTableEnum_CheckValue(e, v))) return true; - _kUpb_FastEnumCheck_Status status = _upb_MiniTable_CheckEnumValueFast(e, v); - if (UPB_LIKELY(status == _kUpb_FastEnumCheck_ValueIsInEnum)) return true; - return _upb_Decoder_CheckEnumSlow(d, ptr, msg, e, field, v); + // Unrecognized enum goes into unknown fields. + // For packed fields the tag could be arbitrarily far in the past, + // so we just re-encode the tag and value here. + const uint32_t tag = + ((uint32_t)field->UPB_PRIVATE(number) << 3) | kUpb_WireType_Varint; + upb_Message* unknown_msg = + field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsExtension ? d->unknown_msg + : msg; + _upb_Decoder_AddUnknownVarints(d, unknown_msg, tag, v); + return false; } UPB_NOINLINE @@ -12234,7 +13012,7 @@ static const char* _upb_Decoder_DecodeEnumArray(upb_Decoder* d, const char* ptr, const upb_MiniTableSub* subs, const upb_MiniTableField* field, wireval* val) { - const upb_MiniTableEnum* e = subs[field->UPB_PRIVATE(submsg_index)].subenum; + const upb_MiniTableEnum* e = _upb_MiniTableSubs_EnumByField(subs, field); if (!_upb_Decoder_CheckEnum(d, ptr, msg, e, field, val)) return ptr; void* mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->size * 4, void); arr->size++; @@ -12305,7 +13083,7 @@ static const char* _upb_Decoder_DecodeEnumPacked( upb_Decoder* d, const char* ptr, upb_Message* msg, upb_Array* arr, const upb_MiniTableSub* subs, const upb_MiniTableField* field, wireval* val) { - const upb_MiniTableEnum* e = subs[field->UPB_PRIVATE(submsg_index)].subenum; + const upb_MiniTableEnum* e = _upb_MiniTableSubs_EnumByField(subs, field); int saved_limit = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, val->size); char* out = UPB_PTR_AT(_upb_array_ptr(arr), arr->size * 4, void); while (!_upb_Decoder_IsDone(d, &ptr)) { @@ -12328,31 +13106,9 @@ static const char* _upb_Decoder_DecodeEnumPacked( upb_Array* _upb_Decoder_CreateArray(upb_Decoder* d, const upb_MiniTableField* field) { - /* Maps descriptor type -> elem_size_lg2. */ - static const uint8_t kElemSizeLg2[] = { - [0] = -1, // invalid descriptor type - [kUpb_FieldType_Double] = 3, - [kUpb_FieldType_Float] = 2, - [kUpb_FieldType_Int64] = 3, - [kUpb_FieldType_UInt64] = 3, - [kUpb_FieldType_Int32] = 2, - [kUpb_FieldType_Fixed64] = 3, - [kUpb_FieldType_Fixed32] = 2, - [kUpb_FieldType_Bool] = 0, - [kUpb_FieldType_String] = UPB_SIZE(3, 4), - [kUpb_FieldType_Group] = UPB_SIZE(2, 3), - [kUpb_FieldType_Message] = UPB_SIZE(2, 3), - [kUpb_FieldType_Bytes] = UPB_SIZE(3, 4), - [kUpb_FieldType_UInt32] = 2, - [kUpb_FieldType_Enum] = 2, - [kUpb_FieldType_SFixed32] = 2, - [kUpb_FieldType_SFixed64] = 3, - [kUpb_FieldType_SInt32] = 2, - [kUpb_FieldType_SInt64] = 3, - }; - - size_t lg2 = kElemSizeLg2[field->UPB_PRIVATE(descriptortype)]; - upb_Array* ret = _upb_Array_New(&d->arena, 4, lg2); + const upb_FieldType field_type = field->UPB_PRIVATE(descriptortype); + const size_t lg2 = upb_FieldType_SizeLg2(field_type); + upb_Array* ret = UPB_PRIVATE(_upb_Array_New)(&d->arena, 4, lg2); if (!ret) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); return ret; } @@ -12447,8 +13203,8 @@ upb_Map* _upb_Decoder_CreateMap(upb_Decoder* d, const upb_MiniTable* entry) { [kUpb_FieldType_SInt64] = 8, }; - const upb_MiniTableField* key_field = &entry->fields[0]; - const upb_MiniTableField* val_field = &entry->fields[1]; + const upb_MiniTableField* key_field = &entry->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* val_field = &entry->UPB_PRIVATE(fields)[1]; char key_size = kSizeInMap[key_field->UPB_PRIVATE(descriptortype)]; char val_size = kSizeInMap[val_field->UPB_PRIVATE(descriptortype)]; UPB_ASSERT(key_field->offset == offsetof(upb_MapEntryData, k)); @@ -12467,12 +13223,12 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr, upb_Map* map = *map_p; upb_MapEntry ent; UPB_ASSERT(upb_MiniTableField_Type(field) == kUpb_FieldType_Message); - const upb_MiniTable* entry = subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* entry = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(entry); - UPB_ASSERT(entry->field_count == 2); - UPB_ASSERT(!upb_IsRepeatedOrMap(&entry->fields[0])); - UPB_ASSERT(!upb_IsRepeatedOrMap(&entry->fields[1])); + UPB_ASSERT(entry->UPB_PRIVATE(field_count) == 2); + UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->UPB_PRIVATE(fields)[0])); + UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->UPB_PRIVATE(fields)[1])); if (!map) { map = _upb_Decoder_CreateMap(d, entry); @@ -12482,11 +13238,14 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr, // Parse map entry. memset(&ent, 0, sizeof(ent)); - if (entry->fields[1].UPB_PRIVATE(descriptortype) == kUpb_FieldType_Message || - entry->fields[1].UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group) { + if (entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) == + kUpb_FieldType_Message || + entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) == + kUpb_FieldType_Group) { // Create proactively to handle the case where it doesn't appear. upb_TaggedMessagePtr msg; - _upb_Decoder_NewSubMessage(d, entry->subs, &entry->fields[1], &msg); + _upb_Decoder_NewSubMessage(d, entry->UPB_PRIVATE(subs), + &entry->UPB_PRIVATE(fields)[1], &msg); ent.data.v.val = upb_value_uintptr(msg); } @@ -12498,14 +13257,15 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr, if (size != 0) { char* buf; size_t size; - uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Delimited; + uint32_t tag = + ((uint32_t)field->UPB_PRIVATE(number) << 3) | kUpb_WireType_Delimited; upb_EncodeStatus status = upb_Encode(&ent.data, entry, 0, &d->arena, &buf, &size); if (status != kUpb_EncodeStatus_Ok) { _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } _upb_Decoder_AddUnknownVarints(d, msg, tag, size); - if (!_upb_Message_AddUnknown(msg, buf, size, &d->arena)) { + if (!UPB_PRIVATE(_upb_Message_AddUnknown)(msg, buf, size, &d->arena)) { _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } } else { @@ -12527,21 +13287,22 @@ static const char* _upb_Decoder_DecodeToSubMessage( if (UPB_UNLIKELY(op == kUpb_DecodeOp_Enum) && !_upb_Decoder_CheckEnum(d, ptr, msg, - subs[field->UPB_PRIVATE(submsg_index)].subenum, + _upb_MiniTableSubs_EnumByField(subs, field), field, val)) { return ptr; } /* Set presence if necessary. */ if (field->presence > 0) { - _upb_sethas_field(msg, field); + UPB_PRIVATE(_upb_Message_SetHasbit)(msg, field); } else if (field->presence < 0) { /* Oneof case */ - uint32_t* oneof_case = _upb_oneofcase_field(msg, field); - if (op == kUpb_DecodeOp_SubMessage && *oneof_case != field->number) { + uint32_t* oneof_case = UPB_PRIVATE(_upb_Message_OneofCasePtr)(msg, field); + if (op == kUpb_DecodeOp_SubMessage && + *oneof_case != field->UPB_PRIVATE(number)) { memset(mem, 0, sizeof(void*)); } - *oneof_case = field->number; + *oneof_case = field->UPB_PRIVATE(number); } /* Store into message. */ @@ -12587,15 +13348,15 @@ static const char* _upb_Decoder_DecodeToSubMessage( UPB_NOINLINE const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, const upb_Message* msg, - const upb_MiniTable* l) { - UPB_ASSERT(l->required_count); + const upb_MiniTable* m) { + UPB_ASSERT(m->UPB_PRIVATE(required_count)); if (UPB_LIKELY((d->options & kUpb_DecodeOption_CheckRequired) == 0)) { return ptr; } uint64_t msg_head; memcpy(&msg_head, msg, 8); msg_head = _upb_BigEndian_Swap64(msg_head); - if (upb_MiniTable_requiredmask(l) & ~msg_head) { + if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) { d->missing_required = true; } return ptr; @@ -12604,11 +13365,11 @@ const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, UPB_FORCEINLINE static bool _upb_Decoder_TryFastDispatch(upb_Decoder* d, const char** ptr, upb_Message* msg, - const upb_MiniTable* layout) { + const upb_MiniTable* m) { #if UPB_FASTTABLE - if (layout && layout->table_mask != (unsigned char)-1) { + if (m && m->UPB_PRIVATE(table_mask) != (unsigned char)-1) { uint16_t tag = _upb_FastDecoder_LoadTag(*ptr); - intptr_t table = decode_totable(layout); + intptr_t table = decode_totable(m); *ptr = _upb_FastDecoder_TagDispatch(d, *ptr, msg, table, 0, tag); return true; } @@ -12657,9 +13418,11 @@ static void upb_Decoder_AddKnownMessageSetItem( _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } upb_Message* submsg = _upb_Decoder_NewSubMessage( - d, &ext->ext->sub, &ext->ext->field, (upb_TaggedMessagePtr*)&ext->data); - upb_DecodeStatus status = upb_Decode(data, size, submsg, item_mt->sub.submsg, - d->extreg, d->options, &d->arena); + d, &ext->ext->UPB_PRIVATE(sub), upb_MiniTableExtension_AsField(ext->ext), + (upb_TaggedMessagePtr*)&ext->data); + upb_DecodeStatus status = upb_Decode( + data, size, submsg, upb_MiniTableExtension_GetSubMessage(item_mt), + d->extreg, d->options, &d->arena); if (status != kUpb_DecodeStatus_Ok) _upb_Decoder_ErrorJmp(d, status); } @@ -12680,9 +13443,11 @@ static void upb_Decoder_AddUnknownMessageSetItem(upb_Decoder* d, ptr = upb_Decoder_EncodeVarint32(kEndItemTag, ptr); char* end = ptr; - if (!_upb_Message_AddUnknown(msg, buf, split - buf, &d->arena) || - !_upb_Message_AddUnknown(msg, message_data, message_size, &d->arena) || - !_upb_Message_AddUnknown(msg, split, end - split, &d->arena)) { + if (!UPB_PRIVATE(_upb_Message_AddUnknown)(msg, buf, split - buf, &d->arena) || + !UPB_PRIVATE(_upb_Message_AddUnknown)(msg, message_data, message_size, + &d->arena) || + !UPB_PRIVATE(_upb_Message_AddUnknown)(msg, split, end - split, + &d->arena)) { _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } } @@ -12762,34 +13527,34 @@ static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d, if (t == NULL) return &none; size_t idx = ((size_t)field_number) - 1; // 0 wraps to SIZE_MAX - if (idx < t->dense_below) { + if (idx < t->UPB_PRIVATE(dense_below)) { /* Fastest case: index into dense fields. */ goto found; } - if (t->dense_below < t->field_count) { + if (t->UPB_PRIVATE(dense_below) < t->UPB_PRIVATE(field_count)) { /* Linear search non-dense fields. Resume scanning from last_field_index * since fields are usually in order. */ size_t last = *last_field_index; - for (idx = last; idx < t->field_count; idx++) { - if (t->fields[idx].number == field_number) { + for (idx = last; idx < t->UPB_PRIVATE(field_count); idx++) { + if (t->UPB_PRIVATE(fields)[idx].UPB_PRIVATE(number) == field_number) { goto found; } } - for (idx = t->dense_below; idx < last; idx++) { - if (t->fields[idx].number == field_number) { + for (idx = t->UPB_PRIVATE(dense_below); idx < last; idx++) { + if (t->UPB_PRIVATE(fields)[idx].UPB_PRIVATE(number) == field_number) { goto found; } } } if (d->extreg) { - switch (t->ext) { + switch (t->UPB_PRIVATE(ext)) { case kUpb_ExtMode_Extendable: { const upb_MiniTableExtension* ext = upb_ExtensionRegistry_Lookup(d->extreg, t, field_number); - if (ext) return &ext->field; + if (ext) return upb_MiniTableExtension_AsField(ext); break; } case kUpb_ExtMode_IsMessageSet: @@ -12805,9 +13570,9 @@ static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d, return &none; /* Unknown field. */ found: - UPB_ASSERT(t->fields[idx].number == field_number); + UPB_ASSERT(t->UPB_PRIVATE(fields)[idx].UPB_PRIVATE(number) == field_number); *last_field_index = idx; - return &t->fields[idx]; + return &t->UPB_PRIVATE(fields)[idx]; } int _upb_Decoder_GetVarintOp(const upb_MiniTableField* field) { @@ -12842,10 +13607,11 @@ static void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt, const upb_MiniTableField* field, int* op) { // If sub-message is not linked, treat as unknown. - if (field->mode & kUpb_LabelFlags_IsExtension) return; - const upb_MiniTableSub* sub = &mt->subs[field->UPB_PRIVATE(submsg_index)]; + if (field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsExtension) return; + const upb_MiniTable* mt_sub = + _upb_MiniTableSubs_MessageByField(mt->UPB_PRIVATE(subs), field); if ((d->options & kUpb_DecodeOption_ExperimentalAllowUnlinked) || - sub->submsg != &_kUpb_MiniTable_Empty) { + !UPB_PRIVATE(_upb_MiniTable_IsEmpty)(mt_sub)) { return; } #ifndef NDEBUG @@ -12856,7 +13622,7 @@ static void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt, do { UPB_ASSERT(upb_MiniTableField_CType(oneof) == kUpb_CType_Message); const upb_MiniTableSub* oneof_sub = - &mt->subs[oneof->UPB_PRIVATE(submsg_index)]; + &mt->UPB_PRIVATE(subs)[oneof->UPB_PRIVATE(submsg_index)]; UPB_ASSERT(!oneof_sub); } while (upb_MiniTable_NextOneofField(mt, &oneof)); } @@ -12915,7 +13681,7 @@ int _upb_Decoder_GetDelimitedOp(upb_Decoder* d, const upb_MiniTable* mt, }; int ndx = field->UPB_PRIVATE(descriptortype); - if (upb_FieldMode_Get(field) == kUpb_FieldMode_Array) ndx += kRepeatedBase; + if (upb_MiniTableField_IsArray(field)) ndx += kRepeatedBase; int op = kDelimitedOps[ndx]; if (op == kUpb_DecodeOp_SubMessage) { @@ -12962,7 +13728,7 @@ static const char* _upb_Decoder_DecodeWireValue(upb_Decoder* d, const char* ptr, *op = _upb_Decoder_GetDelimitedOp(d, mt, field); return ptr; case kUpb_WireType_StartGroup: - val->uint32_val = field->number; + val->uint32_val = field->UPB_PRIVATE(number); if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group) { *op = kUpb_DecodeOp_SubMessage; _upb_Decoder_CheckUnlinked(d, mt, field, op); @@ -12984,8 +13750,8 @@ static const char* _upb_Decoder_DecodeKnownField( upb_Decoder* d, const char* ptr, upb_Message* msg, const upb_MiniTable* layout, const upb_MiniTableField* field, int op, wireval* val) { - const upb_MiniTableSub* subs = layout->subs; - uint8_t mode = field->mode; + const upb_MiniTableSub* subs = layout->UPB_PRIVATE(subs); + uint8_t mode = field->UPB_PRIVATE(mode); if (UPB_UNLIKELY(mode & kUpb_LabelFlags_IsExtension)) { const upb_MiniTableExtension* ext_layout = @@ -12997,7 +13763,7 @@ static const char* _upb_Decoder_DecodeKnownField( } d->unknown_msg = msg; msg = &ext->data; - subs = &ext->ext->sub; + subs = &ext->ext->UPB_PRIVATE(sub); } switch (mode & kUpb_FieldMode_Mask) { @@ -13066,7 +13832,8 @@ static const char* _upb_Decoder_DecodeUnknownField(upb_Decoder* d, start = d->unknown; d->unknown = NULL; } - if (!_upb_Message_AddUnknown(msg, start, ptr - start, &d->arena)) { + if (!UPB_PRIVATE(_upb_Message_AddUnknown)(msg, start, ptr - start, + &d->arena)) { _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } } else if (wire_type == kUpb_WireType_StartGroup) { @@ -13138,7 +13905,7 @@ static const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr, } } - return UPB_UNLIKELY(layout && layout->required_count) + return UPB_UNLIKELY(layout && layout->UPB_PRIVATE(required_count)) ? _upb_Decoder_CheckRequired(d, ptr, msg, layout) : ptr; } @@ -13274,9 +14041,9 @@ static const char* fastdecode_dispatch(UPB_PARSE_PARAMS) { switch (upb_EpsCopyInputStream_IsDoneStatus(&d->input, ptr, &overrun)) { case kUpb_IsDoneStatus_Done: *(uint32_t*)msg |= hasbits; // Sync hasbits. - const upb_MiniTable* l = decode_totablep(table); - return UPB_UNLIKELY(l->required_count) - ? _upb_Decoder_CheckRequired(d, ptr, msg, l) + const upb_MiniTable* m = decode_totablep(table); + return UPB_UNLIKELY(m->UPB_PRIVATE(required_count)) + ? _upb_Decoder_CheckRequired(d, ptr, msg, m) : ptr; case kUpb_IsDoneStatus_NotDone: break; @@ -13376,17 +14143,17 @@ UPB_FORCEINLINE static void* fastdecode_resizearr(upb_Decoder* d, void* dst, fastdecode_arr* farr, int valbytes) { if (UPB_UNLIKELY(dst == farr->end)) { - size_t old_size = farr->arr->capacity; - size_t old_bytes = old_size * valbytes; - size_t new_size = old_size * 2; - size_t new_bytes = new_size * valbytes; + size_t old_capacity = farr->arr->UPB_PRIVATE(capacity); + size_t old_bytes = old_capacity * valbytes; + size_t new_capacity = old_capacity * 2; + size_t new_bytes = new_capacity * valbytes; char* old_ptr = _upb_array_ptr(farr->arr); char* new_ptr = upb_Arena_Realloc(&d->arena, old_ptr, old_bytes, new_bytes); uint8_t elem_size_lg2 = __builtin_ctz(valbytes); - farr->arr->capacity = new_size; - farr->arr->data = _upb_array_tagptr(new_ptr, elem_size_lg2); - dst = (void*)(new_ptr + (old_size * valbytes)); - farr->end = (void*)(new_ptr + (new_size * valbytes)); + UPB_PRIVATE(_upb_Array_SetTaggedPtr)(farr->arr, new_ptr, elem_size_lg2); + farr->arr->UPB_PRIVATE(capacity) = new_capacity; + dst = (void*)(new_ptr + (old_capacity * valbytes)); + farr->end = (void*)(new_ptr + (new_capacity * valbytes)); } return dst; } @@ -13466,13 +14233,13 @@ static void* fastdecode_getfield(upb_Decoder* d, const char* ptr, *(uint32_t*)msg |= *hasbits; *hasbits = 0; if (UPB_LIKELY(!*arr_p)) { - farr->arr = _upb_Array_New(&d->arena, 8, elem_size_lg2); + farr->arr = UPB_PRIVATE(_upb_Array_New)(&d->arena, 8, elem_size_lg2); *arr_p = farr->arr; } else { farr->arr = *arr_p; } begin = _upb_array_ptr(farr->arr); - farr->end = begin + (farr->arr->capacity * valbytes); + farr->end = begin + (farr->arr->UPB_PRIVATE(capacity) * valbytes); *data = _upb_FastDecoder_LoadTag(ptr); return begin + (farr->arr->size * valbytes); } @@ -13751,7 +14518,8 @@ TAGBYTES(p) int elems = size / valbytes; \ \ if (UPB_LIKELY(!arr)) { \ - *arr_p = arr = _upb_Array_New(&d->arena, elems, elem_size_lg2); \ + *arr_p = arr = \ + UPB_PRIVATE(_upb_Array_New)(&d->arena, elems, elem_size_lg2); \ if (!arr) { \ _upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed); \ } \ @@ -13869,12 +14637,14 @@ static const char* fastdecode_longstring_noutf8( UPB_FORCEINLINE static void fastdecode_docopy(upb_Decoder* d, const char* ptr, uint32_t size, - int copy, char* data, upb_StringView* dst) { + int copy, char* data, size_t data_offset, + upb_StringView* dst) { d->arena.head.ptr += copy; - dst->data = data; + dst->data = data + data_offset; UPB_UNPOISON_MEMORY_REGION(data, copy); memcpy(data, ptr, copy); - UPB_POISON_MEMORY_REGION(data + size, copy - size); + UPB_POISON_MEMORY_REGION(data + data_offset + size, + copy - data_offset - size); } #define FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \ @@ -13908,18 +14678,17 @@ static void fastdecode_docopy(upb_Decoder* d, const char* ptr, uint32_t size, \ if (UPB_LIKELY(size <= 15 - tagbytes)) { \ if (arena_has < 16) goto longstr; \ - d->arena.head.ptr += 16; \ - memcpy(buf, ptr - tagbytes - 1, 16); \ - dst->data = buf + tagbytes + 1; \ + fastdecode_docopy(d, ptr - tagbytes - 1, size, 16, buf, tagbytes + 1, \ + dst); \ } else if (UPB_LIKELY(size <= 32)) { \ if (UPB_UNLIKELY(common_has < 32)) goto longstr; \ - fastdecode_docopy(d, ptr, size, 32, buf, dst); \ + fastdecode_docopy(d, ptr, size, 32, buf, 0, dst); \ } else if (UPB_LIKELY(size <= 64)) { \ if (UPB_UNLIKELY(common_has < 64)) goto longstr; \ - fastdecode_docopy(d, ptr, size, 64, buf, dst); \ + fastdecode_docopy(d, ptr, size, 64, buf, 0, dst); \ } else if (UPB_LIKELY(size < 128)) { \ if (UPB_UNLIKELY(common_has < 128)) goto longstr; \ - fastdecode_docopy(d, ptr, size, 128, buf, dst); \ + fastdecode_docopy(d, ptr, size, 128, buf, 0, dst); \ } else { \ goto longstr; \ } \ @@ -14075,9 +14844,9 @@ TAGBYTES(r) /* message fields *************************************************************/ UPB_INLINE -upb_Message* decode_newmsg_ceil(upb_Decoder* d, const upb_MiniTable* l, +upb_Message* decode_newmsg_ceil(upb_Decoder* d, const upb_MiniTable* m, int msg_ceil_bytes) { - size_t size = l->size + sizeof(upb_Message_Internal); + size_t size = m->UPB_PRIVATE(size) + sizeof(upb_Message_Internal); char* msg_data; if (UPB_LIKELY(msg_ceil_bytes > 0 && _upb_ArenaHas(&d->arena) >= msg_ceil_bytes)) { @@ -14123,11 +14892,13 @@ static const char* fastdecode_tosubmsg(upb_EpsCopyInputStream* e, upb_Message** dst; \ uint32_t submsg_idx = (data >> 16) & 0xff; \ const upb_MiniTable* tablep = decode_totablep(table); \ - const upb_MiniTable* subtablep = tablep->subs[submsg_idx].submsg; \ + const upb_MiniTable* subtablep = upb_MiniTableSub_Message( \ + *UPB_PRIVATE(_upb_MiniTable_GetSubByIndex)(tablep, submsg_idx)); \ fastdecode_submsgdata submsg = {decode_totable(subtablep)}; \ fastdecode_arr farr; \ \ - if (subtablep->table_mask == (uint8_t)-1) { \ + if (subtablep->UPB_PRIVATE(table_mask) == (uint8_t)-1) { \ + d->depth++; \ RETURN_GENERIC("submessage doesn't have fast tables."); \ } \ \ @@ -14391,7 +15162,7 @@ static void encode_TaggedMessagePtr(upb_encstate* e, upb_TaggedMessagePtr tagged, const upb_MiniTable* m, size_t* size) { if (upb_TaggedMessagePtr_IsEmpty(tagged)) { - m = &_kUpb_MiniTable_Empty; + m = UPB_PRIVATE(_upb_MiniTable_Empty)(); } encode_message(e, _upb_TaggedMessagePtr_GetMessage(tagged), m, size); } @@ -14446,12 +15217,13 @@ static void encode_scalar(upb_encstate* e, const void* _field_mem, case kUpb_FieldType_Group: { size_t size; upb_TaggedMessagePtr submsg = *(upb_TaggedMessagePtr*)field_mem; - const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subm = + upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); if (submsg == 0) { return; } if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded); - encode_tag(e, f->number, kUpb_WireType_EndGroup); + encode_tag(e, f->UPB_PRIVATE(number), kUpb_WireType_EndGroup); encode_TaggedMessagePtr(e, submsg, subm, &size); wire_type = kUpb_WireType_StartGroup; e->depth++; @@ -14460,7 +15232,8 @@ static void encode_scalar(upb_encstate* e, const void* _field_mem, case kUpb_FieldType_Message: { size_t size; upb_TaggedMessagePtr submsg = *(upb_TaggedMessagePtr*)field_mem; - const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subm = + upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); if (submsg == 0) { return; } @@ -14476,34 +15249,35 @@ static void encode_scalar(upb_encstate* e, const void* _field_mem, } #undef CASE - encode_tag(e, f->number, wire_type); + encode_tag(e, f->UPB_PRIVATE(number), wire_type); } static void encode_array(upb_encstate* e, const upb_Message* msg, const upb_MiniTableSub* subs, const upb_MiniTableField* f) { const upb_Array* arr = *UPB_PTR_AT(msg, f->offset, upb_Array*); - bool packed = f->mode & kUpb_LabelFlags_IsPacked; + bool packed = upb_MiniTableField_IsPacked(f); size_t pre_len = e->limit - e->ptr; if (arr == NULL || arr->size == 0) { return; } -#define VARINT_CASE(ctype, encode) \ - { \ - const ctype* start = _upb_array_constptr(arr); \ - const ctype* ptr = start + arr->size; \ - uint32_t tag = packed ? 0 : (f->number << 3) | kUpb_WireType_Varint; \ - do { \ - ptr--; \ - encode_varint(e, encode); \ - if (tag) encode_varint(e, tag); \ - } while (ptr != start); \ - } \ +#define VARINT_CASE(ctype, encode) \ + { \ + const ctype* start = _upb_array_constptr(arr); \ + const ctype* ptr = start + arr->size; \ + uint32_t tag = \ + packed ? 0 : (f->UPB_PRIVATE(number) << 3) | kUpb_WireType_Varint; \ + do { \ + ptr--; \ + encode_varint(e, encode); \ + if (tag) encode_varint(e, tag); \ + } while (ptr != start); \ + } \ break; -#define TAG(wire_type) (packed ? 0 : (f->number << 3 | wire_type)) +#define TAG(wire_type) (packed ? 0 : (f->UPB_PRIVATE(number) << 3 | wire_type)) switch (f->UPB_PRIVATE(descriptortype)) { case kUpb_FieldType_Double: @@ -14542,21 +15316,22 @@ static void encode_array(upb_encstate* e, const upb_Message* msg, ptr--; encode_bytes(e, ptr->data, ptr->size); encode_varint(e, ptr->size); - encode_tag(e, f->number, kUpb_WireType_Delimited); + encode_tag(e, f->UPB_PRIVATE(number), kUpb_WireType_Delimited); } while (ptr != start); return; } case kUpb_FieldType_Group: { const upb_TaggedMessagePtr* start = _upb_array_constptr(arr); const upb_TaggedMessagePtr* ptr = start + arr->size; - const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subm = + upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded); do { size_t size; ptr--; - encode_tag(e, f->number, kUpb_WireType_EndGroup); + encode_tag(e, f->UPB_PRIVATE(number), kUpb_WireType_EndGroup); encode_TaggedMessagePtr(e, *ptr, subm, &size); - encode_tag(e, f->number, kUpb_WireType_StartGroup); + encode_tag(e, f->UPB_PRIVATE(number), kUpb_WireType_StartGroup); } while (ptr != start); e->depth++; return; @@ -14564,14 +15339,15 @@ static void encode_array(upb_encstate* e, const upb_Message* msg, case kUpb_FieldType_Message: { const upb_TaggedMessagePtr* start = _upb_array_constptr(arr); const upb_TaggedMessagePtr* ptr = start + arr->size; - const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subm = + upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded); do { size_t size; ptr--; encode_TaggedMessagePtr(e, *ptr, subm, &size); encode_varint(e, size); - encode_tag(e, f->number, kUpb_WireType_Delimited); + encode_tag(e, f->UPB_PRIVATE(number), kUpb_WireType_Delimited); } while (ptr != start); e->depth++; return; @@ -14581,19 +15357,19 @@ static void encode_array(upb_encstate* e, const upb_Message* msg, if (packed) { encode_varint(e, e->limit - e->ptr - pre_len); - encode_tag(e, f->number, kUpb_WireType_Delimited); + encode_tag(e, f->UPB_PRIVATE(number), kUpb_WireType_Delimited); } } static void encode_mapentry(upb_encstate* e, uint32_t number, const upb_MiniTable* layout, const upb_MapEntry* ent) { - const upb_MiniTableField* key_field = &layout->fields[0]; - const upb_MiniTableField* val_field = &layout->fields[1]; + const upb_MiniTableField* key_field = &layout->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* val_field = &layout->UPB_PRIVATE(fields)[1]; size_t pre_len = e->limit - e->ptr; size_t size; - encode_scalar(e, &ent->data.v, layout->subs, val_field); - encode_scalar(e, &ent->data.k, layout->subs, key_field); + encode_scalar(e, &ent->data.v, layout->UPB_PRIVATE(subs), val_field); + encode_scalar(e, &ent->data.k, layout->UPB_PRIVATE(subs), key_field); size = (e->limit - e->ptr) - pre_len; encode_varint(e, size); encode_tag(e, number, kUpb_WireType_Delimited); @@ -14603,19 +15379,20 @@ static void encode_map(upb_encstate* e, const upb_Message* msg, const upb_MiniTableSub* subs, const upb_MiniTableField* f) { const upb_Map* map = *UPB_PTR_AT(msg, f->offset, const upb_Map*); - const upb_MiniTable* layout = subs[f->UPB_PRIVATE(submsg_index)].submsg; - UPB_ASSERT(layout->field_count == 2); + const upb_MiniTable* layout = + upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); + UPB_ASSERT(layout->UPB_PRIVATE(field_count) == 2); if (map == NULL) return; if (e->options & kUpb_EncodeOption_Deterministic) { _upb_sortedmap sorted; - _upb_mapsorter_pushmap(&e->sorter, - layout->fields[0].UPB_PRIVATE(descriptortype), map, - &sorted); + _upb_mapsorter_pushmap( + &e->sorter, layout->UPB_PRIVATE(fields)[0].UPB_PRIVATE(descriptortype), + map, &sorted); upb_MapEntry ent; while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) { - encode_mapentry(e, f->number, layout, &ent); + encode_mapentry(e, f->UPB_PRIVATE(number), layout, &ent); } _upb_mapsorter_popmap(&e->sorter, &sorted); } else { @@ -14626,7 +15403,7 @@ static void encode_map(upb_encstate* e, const upb_Message* msg, upb_MapEntry ent; _upb_map_fromkey(key, &ent.data.k, map->key_size); _upb_map_fromvalue(val, &ent.data.v, map->val_size); - encode_mapentry(e, f->number, layout, &ent); + encode_mapentry(e, f->UPB_PRIVATE(number), layout, &ent); } } } @@ -14635,9 +15412,9 @@ static bool encode_shouldencode(upb_encstate* e, const upb_Message* msg, const upb_MiniTableSub* subs, const upb_MiniTableField* f) { if (f->presence == 0) { - /* Proto3 presence or map/array. */ + // Proto3 presence or map/array. const void* mem = UPB_PTR_AT(msg, f->offset, void); - switch (_upb_MiniTableField_GetRep(f)) { + switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(f)) { case kUpb_FieldRep_1Byte: { char ch; memcpy(&ch, mem, 1); @@ -14661,18 +15438,19 @@ static bool encode_shouldencode(upb_encstate* e, const upb_Message* msg, UPB_UNREACHABLE(); } } else if (f->presence > 0) { - /* Proto2 presence: hasbit. */ - return _upb_hasbit_field(msg, f); + // Proto2 presence: hasbit. + return UPB_PRIVATE(_upb_Message_GetHasbit)(msg, f); } else { - /* Field is in a oneof. */ - return _upb_getoneofcase_field(msg, f) == f->number; + // Field is in a oneof. + return UPB_PRIVATE(_upb_Message_GetOneofCase)(msg, f) == + f->UPB_PRIVATE(number); } } static void encode_field(upb_encstate* e, const upb_Message* msg, const upb_MiniTableSub* subs, const upb_MiniTableField* field) { - switch (upb_FieldMode_Get(field)) { + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(field)) { case kUpb_FieldMode_Array: encode_array(e, msg, subs, field); break; @@ -14691,10 +15469,11 @@ static void encode_msgset_item(upb_encstate* e, const upb_Message_Extension* ext) { size_t size; encode_tag(e, kUpb_MsgSet_Item, kUpb_WireType_EndGroup); - encode_message(e, ext->data.ptr, ext->ext->sub.submsg, &size); + encode_message(e, ext->data.ptr, + upb_MiniTableExtension_GetSubMessage(ext->ext), &size); encode_varint(e, size); encode_tag(e, kUpb_MsgSet_Message, kUpb_WireType_Delimited); - encode_varint(e, ext->ext->field.number); + encode_varint(e, upb_MiniTableExtension_Number(ext->ext)); encode_tag(e, kUpb_MsgSet_TypeId, kUpb_WireType_Varint); encode_tag(e, kUpb_MsgSet_Item, kUpb_WireType_StartGroup); } @@ -14704,7 +15483,8 @@ static void encode_ext(upb_encstate* e, const upb_Message_Extension* ext, if (UPB_UNLIKELY(is_message_set)) { encode_msgset_item(e, ext); } else { - encode_field(e, &ext->data, &ext->ext->sub, &ext->ext->field); + encode_field(e, &ext->data, &ext->ext->UPB_PRIVATE(sub), + &ext->ext->UPB_PRIVATE(field)); } } @@ -14712,11 +15492,12 @@ static void encode_message(upb_encstate* e, const upb_Message* msg, const upb_MiniTable* m, size_t* size) { size_t pre_len = e->limit - e->ptr; - if ((e->options & kUpb_EncodeOption_CheckRequired) && m->required_count) { + if ((e->options & kUpb_EncodeOption_CheckRequired) && + m->UPB_PRIVATE(required_count)) { uint64_t msg_head; memcpy(&msg_head, msg, 8); msg_head = _upb_BigEndian_Swap64(msg_head); - if (upb_MiniTable_requiredmask(m) & ~msg_head) { + if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) { encode_err(e, kUpb_EncodeStatus_MissingRequired); } } @@ -14730,7 +15511,7 @@ static void encode_message(upb_encstate* e, const upb_Message* msg, } } - if (m->ext != kUpb_ExtMode_NonExtendable) { + if (m->UPB_PRIVATE(ext) != kUpb_ExtMode_NonExtendable) { /* Encode all extensions together. Unlike C++, we do not attempt to keep * these in field number order relative to normal fields or even to each * other. */ @@ -14741,25 +15522,26 @@ static void encode_message(upb_encstate* e, const upb_Message* msg, _upb_sortedmap sorted; _upb_mapsorter_pushexts(&e->sorter, ext, ext_count, &sorted); while (_upb_sortedmap_nextext(&e->sorter, &sorted, &ext)) { - encode_ext(e, ext, m->ext == kUpb_ExtMode_IsMessageSet); + encode_ext(e, ext, m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet); } _upb_mapsorter_popmap(&e->sorter, &sorted); } else { const upb_Message_Extension* end = ext + ext_count; for (; ext != end; ext++) { - encode_ext(e, ext, m->ext == kUpb_ExtMode_IsMessageSet); + encode_ext(e, ext, m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet); } } } } - if (m->field_count) { - const upb_MiniTableField* f = &m->fields[m->field_count]; - const upb_MiniTableField* first = &m->fields[0]; + if (m->UPB_PRIVATE(field_count)) { + const upb_MiniTableField* f = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; + const upb_MiniTableField* first = &m->UPB_PRIVATE(fields)[0]; while (f != first) { f--; - if (encode_shouldencode(e, msg, m->subs, f)) { - encode_field(e, msg, m->subs, f); + if (encode_shouldencode(e, msg, m->UPB_PRIVATE(subs), f)) { + encode_field(e, msg, m->UPB_PRIVATE(subs), f); } } } @@ -14895,7 +15677,9 @@ const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag, #undef UPB_GNUC_MIN #undef UPB_DESCRIPTOR_UPB_H_FILENAME #undef UPB_DESC +#undef UPB_DESC_MINITABLE #undef UPB_IS_GOOGLE3 #undef UPB_ATOMIC #undef UPB_USE_C11_ATOMICS #undef UPB_PRIVATE +#undef UPB_ONLYBITS diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h index b0621443ed..3f6a270306 100644 --- a/php/ext/google/protobuf/php-upb.h +++ b/php/ext/google/protobuf/php-upb.h @@ -180,6 +180,12 @@ Error, UINTPTR_MAX is undefined #define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only +#ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY +#define UPB_ONLYBITS(x) x +#else +#define UPB_ONLYBITS(x) UPB_PRIVATE(x) +#endif + /* Configure whether fasttable is switched on or not. *************************/ #ifdef __has_attribute @@ -318,8 +324,13 @@ void __asan_unpoison_memory_region(void const volatile *addr, size_t size); #if defined(UPB_IS_GOOGLE3) && !defined(UPB_BOOTSTRAP_STAGE0) #define UPB_DESC(sym) proto2_##sym +#define UPB_DESC_MINITABLE(sym) &proto2__##sym##_msg_init +#elif defined(UPB_BOOTSTRAP_STAGE0) +#define UPB_DESC(sym) google_protobuf_##sym +#define UPB_DESC_MINITABLE(sym) google__protobuf__##sym##_msg_init() #else #define UPB_DESC(sym) google_protobuf_##sym +#define UPB_DESC_MINITABLE(sym) &google__protobuf__##sym##_msg_init #endif #ifndef UPB_BASE_STATUS_H_ @@ -368,6 +379,10 @@ void upb_Status_VAppendErrorFormat(upb_Status* status, const char* fmt, #ifndef UPB_MESSAGE_ACCESSORS_H_ #define UPB_MESSAGE_ACCESSORS_H_ +#include +#include +#include + #ifndef UPB_BASE_DESCRIPTOR_CONSTANTS_H_ #define UPB_BASE_DESCRIPTOR_CONSTANTS_H_ @@ -427,7 +442,34 @@ typedef enum { extern "C" { #endif -UPB_INLINE bool upb_FieldType_IsPackable(upb_FieldType type) { +// Convert from upb_FieldType to upb_CType +UPB_INLINE upb_CType upb_FieldType_CType(upb_FieldType field_type) { + static const upb_CType c_type[] = { + kUpb_CType_Double, // kUpb_FieldType_Double + kUpb_CType_Float, // kUpb_FieldType_Float + kUpb_CType_Int64, // kUpb_FieldType_Int64 + kUpb_CType_UInt64, // kUpb_FieldType_UInt64 + kUpb_CType_Int32, // kUpb_FieldType_Int32 + kUpb_CType_UInt64, // kUpb_FieldType_Fixed64 + kUpb_CType_UInt32, // kUpb_FieldType_Fixed32 + kUpb_CType_Bool, // kUpb_FieldType_Bool + kUpb_CType_String, // kUpb_FieldType_String + kUpb_CType_Message, // kUpb_FieldType_Group + kUpb_CType_Message, // kUpb_FieldType_Message + kUpb_CType_Bytes, // kUpb_FieldType_Bytes + kUpb_CType_UInt32, // kUpb_FieldType_UInt32 + kUpb_CType_Enum, // kUpb_FieldType_Enum + kUpb_CType_Int32, // kUpb_FieldType_SFixed32 + kUpb_CType_Int64, // kUpb_FieldType_SFixed64 + kUpb_CType_Int32, // kUpb_FieldType_SInt32 + kUpb_CType_Int64, // kUpb_FieldType_SInt64 + }; + + // -1 here because the enum is one-based but the table is zero-based. + return c_type[field_type - 1]; +} + +UPB_INLINE bool upb_FieldType_IsPackable(upb_FieldType field_type) { // clang-format off const unsigned kUnpackableTypes = (1 << kUpb_FieldType_String) | @@ -435,7 +477,7 @@ UPB_INLINE bool upb_FieldType_IsPackable(upb_FieldType type) { (1 << kUpb_FieldType_Message) | (1 << kUpb_FieldType_Group); // clang-format on - return (1 << type) & ~kUnpackableTypes; + return (1 << field_type) & ~kUnpackableTypes; } #ifdef __cplusplus @@ -444,13 +486,58 @@ UPB_INLINE bool upb_FieldType_IsPackable(upb_FieldType type) { #endif /* UPB_BASE_DESCRIPTOR_CONSTANTS_H_ */ +#ifndef UPB_BASE_STRING_VIEW_H_ +#define UPB_BASE_STRING_VIEW_H_ -#ifndef UPB_MESSAGE_ARRAY_H_ -#define UPB_MESSAGE_ARRAY_H_ +#include -#include +// Must be last. + +#define UPB_STRINGVIEW_INIT(ptr, len) \ + { ptr, len } + +#define UPB_STRINGVIEW_FORMAT "%.*s" +#define UPB_STRINGVIEW_ARGS(view) (int)(view).size, (view).data + +// LINT.IfChange(struct_definition) +typedef struct { + const char* data; + size_t size; +} upb_StringView; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE upb_StringView upb_StringView_FromDataAndSize(const char* data, + size_t size) { + upb_StringView ret; + ret.data = data; + ret.size = size; + return ret; +} + +UPB_INLINE upb_StringView upb_StringView_FromString(const char* data) { + return upb_StringView_FromDataAndSize(data, strlen(data)); +} + +UPB_INLINE bool upb_StringView_IsEqual(upb_StringView a, upb_StringView b) { + return (a.size == b.size) && (!a.size || !memcmp(a.data, b.data, a.size)); +} + +// LINT.ThenChange( +// GoogleInternalName0, +// //depot/google3/third_party/upb/bits/golang/accessor.go:map_go_string, +// //depot/google3/third_party/upb/bits/typescript/string_view.ts +// ) + +#ifdef __cplusplus +} /* extern "C" */ +#endif +#endif /* UPB_BASE_STRING_VIEW_H_ */ + /* upb_Arena is a specific allocator implementation that uses arena allocation. * The user provides an allocator that will be used to allocate the underlying * arena blocks. Arenas by nature do not require the individual allocations @@ -545,9 +632,11 @@ UPB_INLINE void upb_gfree(void* ptr) { upb_free(&upb_alloc_global, ptr); } typedef struct upb_Arena upb_Arena; +// LINT.IfChange(struct_definition) typedef struct { char *ptr, *end; } _upb_ArenaHead; +// LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/arena.ts) #ifdef __cplusplus extern "C" { @@ -644,6 +733,12 @@ UPB_API_INLINE upb_Arena* upb_Arena_New(void) { #endif /* UPB_MEM_ARENA_H_ */ +#ifndef UPB_MESSAGE_ARRAY_H_ +#define UPB_MESSAGE_ARRAY_H_ + +#include + + // Users should include array.h or map.h instead. // IWYU pragma: private, include "upb/message/array.h" @@ -652,58 +747,9 @@ UPB_API_INLINE upb_Arena* upb_Arena_New(void) { #include -#ifndef UPB_BASE_STRING_VIEW_H_ -#define UPB_BASE_STRING_VIEW_H_ - -#include - -// Must be last. - -#define UPB_STRINGVIEW_INIT(ptr, len) \ - { ptr, len } - -#define UPB_STRINGVIEW_FORMAT "%.*s" -#define UPB_STRINGVIEW_ARGS(view) (int)(view).size, (view).data - -// LINT.IfChange(struct_definition) -typedef struct { - const char* data; - size_t size; -} upb_StringView; -// LINT.ThenChange( -// GoogleInternalName0, -// //depot/google3/third_party/upb/bits/golang/accessor.go:map_go_string -// ) - -#ifdef __cplusplus -extern "C" { -#endif - -UPB_API_INLINE upb_StringView upb_StringView_FromDataAndSize(const char* data, - size_t size) { - upb_StringView ret; - ret.data = data; - ret.size = size; - return ret; -} - -UPB_INLINE upb_StringView upb_StringView_FromString(const char* data) { - return upb_StringView_FromDataAndSize(data, strlen(data)); -} - -UPB_INLINE bool upb_StringView_IsEqual(upb_StringView a, upb_StringView b) { - return a.size == b.size && memcmp(a.data, b.data, a.size) == 0; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* UPB_BASE_STRING_VIEW_H_ */ - -#ifndef UPB_MINI_TABLE_TYPES_H_ -#define UPB_MINI_TABLE_TYPES_H_ +#ifndef UPB_MINI_TABLE_TAGGED_PTR_H_ +#define UPB_MINI_TABLE_TAGGED_PTR_H_ #include @@ -719,10 +765,6 @@ typedef void upb_Message; // Must be last. -#ifdef __cplusplus -extern "C" { -#endif - // When a upb_Message* is stored in a message, array, or map, it is stored in a // tagged form. If the tag bit is set, the referenced upb_Message is of type // _kUpb_MiniTable_Empty (a sentinel message type with no fields) instead of @@ -731,8 +773,13 @@ extern "C" { // // See the documentation for kUpb_DecodeOption_ExperimentalAllowUnlinked for // more information. + typedef uintptr_t upb_TaggedMessagePtr; +#ifdef __cplusplus +extern "C" { +#endif + // Internal-only because empty messages cannot be created by the user. UPB_INLINE upb_TaggedMessagePtr _upb_TaggedMessagePtr_Pack(upb_Message* ptr, bool empty) { @@ -769,7 +816,7 @@ UPB_INLINE upb_Message* _upb_TaggedMessagePtr_GetEmptyMessage( #endif -#endif /* UPB_MINI_TABLE_TYPES_H_ */ +#endif /* UPB_MINI_TABLE_TAGGED_PTR_H_ */ typedef union { bool bool_val; @@ -860,6 +907,10 @@ UPB_API void* upb_Array_MutableDataPtr(upb_Array* arr); #ifndef UPB_MESSAGE_INTERNAL_ACCESSORS_H_ #define UPB_MESSAGE_INTERNAL_ACCESSORS_H_ +#include +#include +#include + #ifndef UPB_MESSAGE_INTERNAL_EXTENSION_H_ #define UPB_MESSAGE_INTERNAL_EXTENSION_H_ @@ -882,6 +933,8 @@ UPB_API void* upb_Array_MutableDataPtr(upb_Array* arr); #ifndef UPB_MINI_TABLE_ENUM_H_ #define UPB_MINI_TABLE_ENUM_H_ +#include + #ifndef UPB_MINI_TABLE_INTERNAL_ENUM_H_ #define UPB_MINI_TABLE_INTERNAL_ENUM_H_ @@ -891,35 +944,34 @@ UPB_API void* upb_Array_MutableDataPtr(upb_Array* arr); // Must be last. struct upb_MiniTableEnum { - uint32_t mask_limit; // Limit enum value that can be tested with mask. - uint32_t value_count; // Number of values after the bitfield. - uint32_t data[]; // Bitmask + enumerated values follow. + uint32_t UPB_PRIVATE(mask_limit); // Highest that can be tested with mask. + uint32_t UPB_PRIVATE(value_count); // Number of values after the bitfield. + uint32_t UPB_PRIVATE(data)[]; // Bitmask + enumerated values follow. }; -typedef enum { - _kUpb_FastEnumCheck_ValueIsInEnum = 0, - _kUpb_FastEnumCheck_ValueIsNotInEnum = 1, - _kUpb_FastEnumCheck_CannotCheckFast = 2, -} _kUpb_FastEnumCheck_Status; - #ifdef __cplusplus extern "C" { #endif -UPB_INLINE _kUpb_FastEnumCheck_Status _upb_MiniTable_CheckEnumValueFast( +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableEnum_CheckValue)( const struct upb_MiniTableEnum* e, uint32_t val) { - if (UPB_UNLIKELY(val >= 64)) return _kUpb_FastEnumCheck_CannotCheckFast; - uint64_t mask = e->data[0] | ((uint64_t)e->data[1] << 32); - return (mask & (1ULL << val)) ? _kUpb_FastEnumCheck_ValueIsInEnum - : _kUpb_FastEnumCheck_ValueIsNotInEnum; -} + if (UPB_LIKELY(val < 64)) { + const uint64_t mask = + e->UPB_PRIVATE(data)[0] | ((uint64_t)e->UPB_PRIVATE(data)[1] << 32); + const uint64_t bit = 1ULL << val; + return (mask & bit) != 0; + } + if (UPB_LIKELY(val < e->UPB_PRIVATE(mask_limit))) { + const uint32_t mask = e->UPB_PRIVATE(data)[val / 32]; + const uint32_t bit = 1ULL << (val % 32); + return (mask & bit) != 0; + } -UPB_INLINE bool _upb_MiniTable_CheckEnumValueSlow( - const struct upb_MiniTableEnum* e, uint32_t val) { - if (val < e->mask_limit) return e->data[val / 32] & (1ULL << (val % 32)); // OPT: binary search long lists? - const uint32_t* start = &e->data[e->mask_limit / 32]; - const uint32_t* limit = &e->data[(e->mask_limit / 32) + e->value_count]; + const uint32_t* start = + &e->UPB_PRIVATE(data)[e->UPB_PRIVATE(mask_limit) / 32]; + const uint32_t* limit = &e->UPB_PRIVATE( + data)[e->UPB_PRIVATE(mask_limit) / 32 + e->UPB_PRIVATE(value_count)]; for (const uint32_t* p = start; p < limit; p++) { if (*p == val) return true; } @@ -942,13 +994,9 @@ extern "C" { #endif // Validates enum value against range defined by enum mini table. -UPB_INLINE bool upb_MiniTableEnum_CheckValue(const struct upb_MiniTableEnum* e, +UPB_INLINE bool upb_MiniTableEnum_CheckValue(const upb_MiniTableEnum* e, uint32_t val) { - _kUpb_FastEnumCheck_Status status = _upb_MiniTable_CheckEnumValueFast(e, val); - if (UPB_UNLIKELY(status == _kUpb_FastEnumCheck_CannotCheckFast)) { - return _upb_MiniTable_CheckEnumValueSlow(e, val); - } - return status == _kUpb_FastEnumCheck_ValueIsInEnum ? true : false; + return UPB_PRIVATE(_upb_MiniTableEnum_CheckValue)(e, val); } #ifdef __cplusplus @@ -961,19 +1009,90 @@ UPB_INLINE bool upb_MiniTableEnum_CheckValue(const struct upb_MiniTableEnum* e, #ifndef UPB_MINI_TABLE_FIELD_H_ #define UPB_MINI_TABLE_FIELD_H_ +#include + #ifndef UPB_MINI_TABLE_INTERNAL_FIELD_H_ #define UPB_MINI_TABLE_INTERNAL_FIELD_H_ +#include +#include + + +#ifndef UPB_MINI_TABLE_INTERNAL_SIZE_LOG2_H_ +#define UPB_MINI_TABLE_INTERNAL_SIZE_LOG2_H_ + +#include #include // Must be last. +#ifdef __cplusplus +extern "C" { +#endif + +// Return the log2 of the storage size in bytes for a upb_CType +UPB_INLINE int upb_CType_SizeLg2(upb_CType c_type) { + static const int8_t size[] = { + 0, // kUpb_CType_Bool + 2, // kUpb_CType_Float + 2, // kUpb_CType_Int32 + 2, // kUpb_CType_UInt32 + 2, // kUpb_CType_Enum + UPB_SIZE(2, 3), // kUpb_CType_Message + 3, // kUpb_CType_Double + 3, // kUpb_CType_Int64 + 3, // kUpb_CType_UInt64 + UPB_SIZE(3, 4), // kUpb_CType_String + UPB_SIZE(3, 4), // kUpb_CType_Bytes + }; + + // -1 here because the enum is one-based but the table is zero-based. + return size[c_type - 1]; +} + +// Return the log2 of the storage size in bytes for a upb_FieldType +UPB_INLINE int upb_FieldType_SizeLg2(upb_FieldType field_type) { + static const int8_t size[] = { + 3, // kUpb_FieldType_Double + 2, // kUpb_FieldType_Float + 3, // kUpb_FieldType_Int64 + 3, // kUpb_FieldType_UInt64 + 2, // kUpb_FieldType_Int32 + 3, // kUpb_FieldType_Fixed64 + 2, // kUpb_FieldType_Fixed32 + 0, // kUpb_FieldType_Bool + UPB_SIZE(3, 4), // kUpb_FieldType_String + UPB_SIZE(2, 3), // kUpb_FieldType_Group + UPB_SIZE(2, 3), // kUpb_FieldType_Message + UPB_SIZE(3, 4), // kUpb_FieldType_Bytes + 2, // kUpb_FieldType_UInt32 + 2, // kUpb_FieldType_Enum + 2, // kUpb_FieldType_SFixed32 + 3, // kUpb_FieldType_SFixed64 + 2, // kUpb_FieldType_SInt32 + 3, // kUpb_FieldType_SInt64 + }; + + // -1 here because the enum is one-based but the table is zero-based. + return size[field_type - 1]; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_SIZE_LOG2_H_ */ + +// Must be last. + +// LINT.IfChange(struct_definition) struct upb_MiniTableField { - uint32_t number; + uint32_t UPB_ONLYBITS(number); uint16_t offset; - int16_t presence; // If >0, hasbit_index. If <0, ~oneof_index + int16_t presence; // If >0, hasbit_index. If <0, ~oneof_index // Indexes into `upb_MiniTable.subs` // Will be set to `kUpb_NoSub` if `descriptortype` != MESSAGE/GROUP/ENUM @@ -982,7 +1101,7 @@ struct upb_MiniTableField { uint8_t UPB_PRIVATE(descriptortype); // upb_FieldMode | upb_LabelFlags | (upb_FieldRep << kUpb_FieldRep_Shift) - uint8_t mode; + uint8_t UPB_ONLYBITS(mode); }; #define kUpb_NoSub ((uint16_t)-1) @@ -1022,213 +1141,205 @@ typedef enum { #define kUpb_FieldRep_Shift 6 -UPB_INLINE upb_FieldRep -_upb_MiniTableField_GetRep(const struct upb_MiniTableField* field) { - return (upb_FieldRep)(field->mode >> kUpb_FieldRep_Shift); -} - #ifdef __cplusplus extern "C" { #endif UPB_INLINE upb_FieldMode -upb_FieldMode_Get(const struct upb_MiniTableField* field) { - return (upb_FieldMode)(field->mode & 3); +UPB_PRIVATE(_upb_MiniTableField_Mode)(const struct upb_MiniTableField* f) { + return (upb_FieldMode)(f->UPB_ONLYBITS(mode) & kUpb_FieldMode_Mask); } -UPB_INLINE void _upb_MiniTableField_CheckIsArray( - const struct upb_MiniTableField* field) { - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_NativePointer); - UPB_ASSUME(upb_FieldMode_Get(field) == kUpb_FieldMode_Array); - UPB_ASSUME(field->presence == 0); +UPB_INLINE upb_FieldRep +UPB_PRIVATE(_upb_MiniTableField_GetRep)(const struct upb_MiniTableField* f) { + return (upb_FieldRep)(f->UPB_ONLYBITS(mode) >> kUpb_FieldRep_Shift); } -UPB_INLINE void _upb_MiniTableField_CheckIsMap( - const struct upb_MiniTableField* field) { - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_NativePointer); - UPB_ASSUME(upb_FieldMode_Get(field) == kUpb_FieldMode_Map); - UPB_ASSUME(field->presence == 0); +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsArray)( + const struct upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_Mode)(f) == kUpb_FieldMode_Array; } -UPB_INLINE bool upb_IsRepeatedOrMap(const struct upb_MiniTableField* field) { - // This works because upb_FieldMode has no value 3. - return !(field->mode & kUpb_FieldMode_Scalar); +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsMap)( + const struct upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_Mode)(f) == kUpb_FieldMode_Map; } -UPB_INLINE bool upb_IsSubMessage(const struct upb_MiniTableField* field) { - return field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Message || - field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group; +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsScalar)( + const struct upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_Mode)(f) == kUpb_FieldMode_Scalar; } -#ifdef __cplusplus -} /* extern "C" */ -#endif - +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsAlternate)( + const struct upb_MiniTableField* f) { + return (f->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsAlternate) != 0; +} -#endif /* UPB_MINI_TABLE_INTERNAL_FIELD_H_ */ +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsExtension)( + const struct upb_MiniTableField* f) { + return (f->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsExtension) != 0; +} -#ifndef UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ -#define UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsPacked)( + const struct upb_MiniTableField* f) { + return (f->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsPacked) != 0; +} +UPB_INLINE upb_FieldType +UPB_PRIVATE(_upb_MiniTableField_Type)(const struct upb_MiniTableField* f) { + const upb_FieldType type = (upb_FieldType)f->UPB_PRIVATE(descriptortype); + if (UPB_PRIVATE(_upb_MiniTableField_IsAlternate)(f)) { + if (type == kUpb_FieldType_Int32) return kUpb_FieldType_Enum; + if (type == kUpb_FieldType_Bytes) return kUpb_FieldType_String; + UPB_ASSERT(false); + } + return type; +} -// Must be last. +UPB_INLINE upb_CType +UPB_PRIVATE(_upb_MiniTableField_CType)(const struct upb_MiniTableField* f) { + return upb_FieldType_CType(UPB_PRIVATE(_upb_MiniTableField_Type)(f)); +} -struct upb_Decoder; -typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr, - upb_Message* msg, intptr_t table, - uint64_t hasbits, uint64_t data); -typedef struct { - uint64_t field_data; - _upb_FieldParser* field_parser; -} _upb_FastTable_Entry; +UPB_INLINE char _upb_MiniTableField_HasbitMask( + const struct upb_MiniTableField* f) { + UPB_ASSERT(f->presence > 0); + const size_t index = f->presence; + return 1 << (index % 8); +} -typedef enum { - kUpb_ExtMode_NonExtendable = 0, // Non-extendable message. - kUpb_ExtMode_Extendable = 1, // Normal extendable message. - kUpb_ExtMode_IsMessageSet = 2, // MessageSet message. - kUpb_ExtMode_IsMessageSet_ITEM = - 3, // MessageSet item (temporary only, see decode.c) +UPB_INLINE size_t +_upb_MiniTableField_HasbitOffset(const struct upb_MiniTableField* f) { + UPB_ASSERT(f->presence > 0); + const size_t index = f->presence; + return index / 8; +} - // During table building we steal a bit to indicate that the message is a map - // entry. *Only* used during table building! - kUpb_ExtMode_IsMapEntry = 4, -} upb_ExtMode; +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsClosedEnum)( + const struct upb_MiniTableField* f) { + return f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum; +} -union upb_MiniTableSub; +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsInOneof)( + const struct upb_MiniTableField* f) { + return f->presence < 0; +} -// upb_MiniTable represents the memory layout of a given upb_MessageDef. -// The members are public so generated code can initialize them, -// but users MUST NOT directly read or write any of its members. -struct upb_MiniTable { - const union upb_MiniTableSub* subs; - const struct upb_MiniTableField* fields; +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsSubMessage)( + const struct upb_MiniTableField* f) { + return f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Message || + f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group; +} - // Must be aligned to sizeof(void*). Doesn't include internal members like - // unknown fields, extension dict, pointer to msglayout, etc. - uint16_t size; +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_HasPresence)( + const struct upb_MiniTableField* f) { + if (UPB_PRIVATE(_upb_MiniTableField_IsExtension)(f)) { + return UPB_PRIVATE(_upb_MiniTableField_IsScalar)(f); + } else { + return f->presence != 0; + } +} - uint16_t field_count; - uint8_t ext; // upb_ExtMode, declared as uint8_t so sizeof(ext) == 1 - uint8_t dense_below; - uint8_t table_mask; - uint8_t required_count; // Required fields have the lowest hasbits. +UPB_INLINE uint32_t +UPB_PRIVATE(_upb_MiniTableField_Number)(const struct upb_MiniTableField* f) { + return f->UPB_ONLYBITS(number); +} - // To statically initialize the tables of variable length, we need a flexible - // array member, and we need to compile in gnu99 mode (constant initialization - // of flexible array members is a GNU extension, not in C99 unfortunately. - _upb_FastTable_Entry fasttable[]; -}; +UPB_INLINE size_t +_upb_MiniTableField_OneofOffset(const struct upb_MiniTableField* f) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_IsInOneof)(f)); + return ~(ptrdiff_t)f->presence; +} -#ifdef __cplusplus -extern "C" { -#endif +UPB_INLINE void UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)( + const struct upb_MiniTableField* f) { + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == + kUpb_FieldRep_NativePointer); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_IsArray)(f)); + UPB_ASSUME(f->presence == 0); +} -// A MiniTable for an empty message, used for unlinked sub-messages. -extern const struct upb_MiniTable _kUpb_MiniTable_Empty; +UPB_INLINE void UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)( + const struct upb_MiniTableField* f) { + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == + kUpb_FieldRep_NativePointer); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_IsMap)(f)); + UPB_ASSUME(f->presence == 0); +} -// Computes a bitmask in which the |l->required_count| lowest bits are set, -// except that we skip the lowest bit (because upb never uses hasbit 0). -// -// Sample output: -// requiredmask(1) => 0b10 (0x2) -// requiredmask(5) => 0b111110 (0x3e) -UPB_INLINE uint64_t upb_MiniTable_requiredmask(const struct upb_MiniTable* l) { - int n = l->required_count; - assert(0 < n && n <= 63); - return ((1ULL << n) - 1) << 1; +UPB_INLINE size_t UPB_PRIVATE(_upb_MiniTableField_ElemSizeLg2)( + const struct upb_MiniTableField* f) { + return upb_FieldType_SizeLg2((upb_FieldType)f->UPB_PRIVATE(descriptortype)); } +// LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/mini_table_field.ts) + #ifdef __cplusplus } /* extern "C" */ #endif -#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */ -#ifndef UPB_MINI_TABLE_INTERNAL_SUB_H_ -#define UPB_MINI_TABLE_INTERNAL_SUB_H_ - - -union upb_MiniTableSub { - const struct upb_MiniTable* submsg; - const struct upb_MiniTableEnum* subenum; -}; - -#endif /* UPB_MINI_TABLE_INTERNAL_SUB_H_ */ +#endif /* UPB_MINI_TABLE_INTERNAL_FIELD_H_ */ // Must be last. +typedef struct upb_MiniTableField upb_MiniTableField; + #ifdef __cplusplus extern "C" { #endif -typedef struct upb_MiniTableField upb_MiniTableField; +UPB_API_INLINE upb_CType upb_MiniTableField_CType(const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_CType)(f); +} -UPB_API_INLINE upb_FieldType -upb_MiniTableField_Type(const upb_MiniTableField* field) { - if (field->mode & kUpb_LabelFlags_IsAlternate) { - if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Int32) { - return kUpb_FieldType_Enum; - } else if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bytes) { - return kUpb_FieldType_String; - } else { - UPB_ASSERT(false); - } - } - return (upb_FieldType)field->UPB_PRIVATE(descriptortype); +UPB_API_INLINE bool upb_MiniTableField_HasPresence( + const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_HasPresence)(f); } -UPB_API_INLINE upb_CType upb_MiniTableField_CType(const upb_MiniTableField* f) { - switch (upb_MiniTableField_Type(f)) { - case kUpb_FieldType_Double: - return kUpb_CType_Double; - case kUpb_FieldType_Float: - return kUpb_CType_Float; - case kUpb_FieldType_Int64: - case kUpb_FieldType_SInt64: - case kUpb_FieldType_SFixed64: - return kUpb_CType_Int64; - case kUpb_FieldType_Int32: - case kUpb_FieldType_SFixed32: - case kUpb_FieldType_SInt32: - return kUpb_CType_Int32; - case kUpb_FieldType_UInt64: - case kUpb_FieldType_Fixed64: - return kUpb_CType_UInt64; - case kUpb_FieldType_UInt32: - case kUpb_FieldType_Fixed32: - return kUpb_CType_UInt32; - case kUpb_FieldType_Enum: - return kUpb_CType_Enum; - case kUpb_FieldType_Bool: - return kUpb_CType_Bool; - case kUpb_FieldType_String: - return kUpb_CType_String; - case kUpb_FieldType_Bytes: - return kUpb_CType_Bytes; - case kUpb_FieldType_Group: - case kUpb_FieldType_Message: - return kUpb_CType_Message; - } - UPB_UNREACHABLE(); +UPB_API_INLINE bool upb_MiniTableField_IsArray(const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_IsArray)(f); +} + +UPB_API_INLINE bool upb_MiniTableField_IsClosedEnum( + const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_IsClosedEnum)(f); } UPB_API_INLINE bool upb_MiniTableField_IsExtension( - const upb_MiniTableField* field) { - return field->mode & kUpb_LabelFlags_IsExtension; + const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_IsExtension)(f); } -UPB_API_INLINE bool upb_MiniTableField_IsClosedEnum( - const upb_MiniTableField* field) { - return field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum; +UPB_API_INLINE bool upb_MiniTableField_IsInOneof(const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_IsInOneof)(f); } -UPB_API_INLINE bool upb_MiniTableField_HasPresence( - const upb_MiniTableField* field) { - if (upb_MiniTableField_IsExtension(field)) { - return !upb_IsRepeatedOrMap(field); - } else { - return field->presence != 0; - } +UPB_API_INLINE bool upb_MiniTableField_IsMap(const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_IsMap)(f); +} + +UPB_API_INLINE bool upb_MiniTableField_IsPacked(const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_IsPacked)(f); +} + +UPB_API_INLINE bool upb_MiniTableField_IsScalar(const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_IsScalar)(f); +} + +UPB_API_INLINE bool upb_MiniTableField_IsSubMessage( + const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_IsSubMessage)(f); +} + +UPB_API_INLINE uint32_t upb_MiniTableField_Number(const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_Number)(f); +} + +UPB_API_INLINE upb_FieldType +upb_MiniTableField_Type(const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_Type)(f); } #ifdef __cplusplus @@ -1238,46 +1349,246 @@ UPB_API_INLINE bool upb_MiniTableField_HasPresence( #endif /* UPB_MINI_TABLE_FIELD_H_ */ +#ifndef UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ +#define UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ + + +#ifndef UPB_MINI_TABLE_INTERNAL_SUB_H_ +#define UPB_MINI_TABLE_INTERNAL_SUB_H_ + +// Must be last. + +union upb_MiniTableSub { + const struct upb_MiniTable* UPB_PRIVATE(submsg); + const struct upb_MiniTableEnum* UPB_PRIVATE(subenum); +}; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE union upb_MiniTableSub UPB_PRIVATE(_upb_MiniTableSub_FromEnum)( + const struct upb_MiniTableEnum* subenum) { + union upb_MiniTableSub out; + out.UPB_PRIVATE(subenum) = subenum; + return out; +} + +UPB_INLINE union upb_MiniTableSub UPB_PRIVATE(_upb_MiniTableSub_FromMessage)( + const struct upb_MiniTable* submsg) { + union upb_MiniTableSub out; + out.UPB_PRIVATE(submsg) = submsg; + return out; +} + +UPB_INLINE const struct upb_MiniTableEnum* UPB_PRIVATE(_upb_MiniTableSub_Enum)( + const union upb_MiniTableSub sub) { + return sub.UPB_PRIVATE(subenum); +} + +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTableSub_Message)( + const union upb_MiniTableSub sub) { + return sub.UPB_PRIVATE(submsg); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_SUB_H_ */ + // Must be last. +struct upb_Decoder; +typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr, + upb_Message* msg, intptr_t table, + uint64_t hasbits, uint64_t data); +typedef struct { + uint64_t field_data; + _upb_FieldParser* field_parser; +} _upb_FastTable_Entry; + +typedef enum { + kUpb_ExtMode_NonExtendable = 0, // Non-extendable message. + kUpb_ExtMode_Extendable = 1, // Normal extendable message. + kUpb_ExtMode_IsMessageSet = 2, // MessageSet message. + kUpb_ExtMode_IsMessageSet_ITEM = + 3, // MessageSet item (temporary only, see decode.c) + + // During table building we steal a bit to indicate that the message is a map + // entry. *Only* used during table building! + kUpb_ExtMode_IsMapEntry = 4, +} upb_ExtMode; + +// upb_MiniTable represents the memory layout of a given upb_MessageDef. +// The members are public so generated code can initialize them, +// but users MUST NOT directly read or write any of its members. +// LINT.IfChange(minitable_struct_definition) +struct upb_MiniTable { + const union upb_MiniTableSub* UPB_PRIVATE(subs); + const struct upb_MiniTableField* UPB_ONLYBITS(fields); + + // Must be aligned to sizeof(void*). Doesn't include internal members like + // unknown fields, extension dict, pointer to msglayout, etc. + uint16_t UPB_PRIVATE(size); + + uint16_t UPB_ONLYBITS(field_count); + + uint8_t UPB_PRIVATE(ext); // upb_ExtMode, uint8_t here so sizeof(ext) == 1 + uint8_t UPB_PRIVATE(dense_below); + uint8_t UPB_PRIVATE(table_mask); + uint8_t UPB_PRIVATE(required_count); // Required fields have the low hasbits. + + // To statically initialize the tables of variable length, we need a flexible + // array member, and we need to compile in gnu99 mode (constant initialization + // of flexible array members is a GNU extension, not in C99 unfortunately. + _upb_FastTable_Entry UPB_PRIVATE(fasttable)[]; +}; +// LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/mini_table.ts) + #ifdef __cplusplus extern "C" { #endif +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTable_Empty)(void) { + extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty); + + return &UPB_PRIVATE(_kUpb_MiniTable_Empty); +} + +UPB_INLINE int UPB_PRIVATE(_upb_MiniTable_FieldCount)( + const struct upb_MiniTable* m) { + return m->UPB_ONLYBITS(field_count); +} + +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_IsEmpty)( + const struct upb_MiniTable* m) { + extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty); + + return m == &UPB_PRIVATE(_kUpb_MiniTable_Empty); +} + +UPB_INLINE const struct upb_MiniTableField* UPB_PRIVATE( + _upb_MiniTable_GetFieldByIndex)(const struct upb_MiniTable* m, uint32_t i) { + return &m->UPB_ONLYBITS(fields)[i]; +} + +UPB_INLINE const union upb_MiniTableSub* UPB_PRIVATE( + _upb_MiniTable_GetSubByIndex)(const struct upb_MiniTable* m, uint32_t i) { + return &m->UPB_PRIVATE(subs)[i]; +} + +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE( + _upb_MiniTable_GetSubMessageTable)(const struct upb_MiniTable* m, + const struct upb_MiniTableField* f) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_CType)(f) == kUpb_CType_Message); + const struct upb_MiniTable* ret = UPB_PRIVATE(_upb_MiniTableSub_Message)( + m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); + UPB_ASSUME(ret); + return UPB_PRIVATE(_upb_MiniTable_IsEmpty)(ret) ? NULL : ret; +} + +UPB_INLINE const struct upb_MiniTableEnum* UPB_PRIVATE( + _upb_MiniTable_GetSubEnumTable)(const struct upb_MiniTable* m, + const struct upb_MiniTableField* f) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_CType)(f) == kUpb_CType_Enum); + return UPB_PRIVATE(_upb_MiniTableSub_Enum)( + m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); +} + +UPB_INLINE const struct upb_MiniTableField* UPB_PRIVATE(_upb_MiniTable_MapKey)( + const struct upb_MiniTable* m) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTable_FieldCount)(m) == 2); + const struct upb_MiniTableField* f = + UPB_PRIVATE(_upb_MiniTable_GetFieldByIndex)(m, 0); + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_Number)(f) == 1); + return f; +} + +UPB_INLINE const struct upb_MiniTableField* UPB_PRIVATE( + _upb_MiniTable_MapValue)(const struct upb_MiniTable* m) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTable_FieldCount)(m) == 2); + const struct upb_MiniTableField* f = + UPB_PRIVATE(_upb_MiniTable_GetFieldByIndex)(m, 1); + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_Number)(f) == 2); + return f; +} + +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_MessageFieldIsLinked)( + const struct upb_MiniTable* m, const struct upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTable_GetSubMessageTable)(m, f) != NULL; +} + +// Computes a bitmask in which the |m->required_count| lowest bits are set, +// except that we skip the lowest bit (because upb never uses hasbit 0). +// +// Sample output: +// RequiredMask(1) => 0b10 (0x2) +// RequiredMask(5) => 0b111110 (0x3e) +UPB_INLINE uint64_t +UPB_PRIVATE(_upb_MiniTable_RequiredMask)(const struct upb_MiniTable* m) { + int n = m->UPB_PRIVATE(required_count); + UPB_ASSERT(0 < n && n <= 63); + return ((1ULL << n) - 1) << 1; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */ + +// Must be last. + typedef struct upb_MiniTable upb_MiniTable; +#ifdef __cplusplus +extern "C" { +#endif + UPB_API const upb_MiniTableField* upb_MiniTable_FindFieldByNumber( - const upb_MiniTable* table, uint32_t number); + const upb_MiniTable* m, uint32_t number); UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_GetFieldByIndex( - const upb_MiniTable* t, uint32_t index) { - return &t->fields[index]; + const upb_MiniTable* m, uint32_t index) { + return UPB_PRIVATE(_upb_MiniTable_GetFieldByIndex)(m, index); } -// Returns the MiniTable for this message field. If the field is unlinked, -// returns NULL. +UPB_API_INLINE int upb_MiniTable_FieldCount(const upb_MiniTable* m) { + return UPB_PRIVATE(_upb_MiniTable_FieldCount)(m); +} + +// Returns the MiniTable for a message field, NULL if the field is unlinked. UPB_API_INLINE const upb_MiniTable* upb_MiniTable_GetSubMessageTable( - const upb_MiniTable* mini_table, const upb_MiniTableField* field) { - UPB_ASSERT(upb_MiniTableField_CType(field) == kUpb_CType_Message); - const upb_MiniTable* ret = - mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg; - UPB_ASSUME(ret); - return ret == &_kUpb_MiniTable_Empty ? NULL : ret; + const upb_MiniTable* m, const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTable_GetSubMessageTable)(m, f); } -// Returns the MiniTableEnum for this enum field. If the field is unlinked, -// returns NULL. +// Returns the MiniTableEnum for a message field, NULL if the field is unlinked. UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( - const upb_MiniTable* mini_table, const upb_MiniTableField* field) { - UPB_ASSERT(upb_MiniTableField_CType(field) == kUpb_CType_Enum); - return mini_table->subs[field->UPB_PRIVATE(submsg_index)].subenum; + const upb_MiniTable* m, const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTable_GetSubEnumTable)(m, f); +} + +// Returns the MiniTableField for the key of a map. +UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_MapKey( + const upb_MiniTable* m) { + return UPB_PRIVATE(_upb_MiniTable_MapKey)(m); +} + +// Returns the MiniTableField for the value of a map. +UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_MapValue( + const upb_MiniTable* m) { + return UPB_PRIVATE(_upb_MiniTable_MapValue)(m); } // Returns true if this MiniTable field is linked to a MiniTable for the // sub-message. UPB_API_INLINE bool upb_MiniTable_MessageFieldIsLinked( - const upb_MiniTable* mini_table, const upb_MiniTableField* field) { - return upb_MiniTable_GetSubMessageTable(mini_table, field) != NULL; + const upb_MiniTable* m, const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTable_MessageFieldIsLinked)(m, f); } // If this field is in a oneof, returns the first field in the oneof. @@ -1315,13 +1626,7 @@ extern "C" { #endif // Creates a new message with the given mini_table on the given arena. -UPB_API upb_Message* upb_Message_New(const upb_MiniTable* mini_table, - upb_Arena* arena); - -// Adds unknown data (serialized protobuf data) to the given message. -// The data is copied into the message instance. -void upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len, - upb_Arena* arena); +UPB_API upb_Message* upb_Message_New(const upb_MiniTable* m, upb_Arena* arena); // Returns a reference to the message's unknown data. const char* upb_Message_GetUnknown(const upb_Message* msg, size_t* len); @@ -1342,26 +1647,90 @@ size_t upb_Message_ExtensionCount(const upb_Message* msg); #ifndef UPB_MINI_TABLE_EXTENSION_H_ #define UPB_MINI_TABLE_EXTENSION_H_ +#include + #ifndef UPB_MINI_TABLE_INTERNAL_EXTENSION_H_ #define UPB_MINI_TABLE_INTERNAL_EXTENSION_H_ +#include + // Must be last. struct upb_MiniTableExtension { // Do not move this field. We need to be able to alias pointers. - struct upb_MiniTableField field; + struct upb_MiniTableField UPB_PRIVATE(field); - const struct upb_MiniTable* extendee; - union upb_MiniTableSub sub; // NULL unless submessage or proto2 enum + const struct upb_MiniTable* UPB_PRIVATE(extendee); + union upb_MiniTableSub UPB_PRIVATE(sub); // NULL unless submsg or proto2 enum }; +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE const struct upb_MiniTableField* UPB_PRIVATE( + _upb_MiniTableExtension_AsField)(const struct upb_MiniTableExtension* e) { + return (const struct upb_MiniTableField*)&e->UPB_PRIVATE(field); +} + +UPB_INLINE uint32_t UPB_PRIVATE(_upb_MiniTableExtension_Number)( + const struct upb_MiniTableExtension* e) { + return e->UPB_PRIVATE(field).UPB_ONLYBITS(number); +} + +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE( + _upb_MiniTableExtension_GetSubMessage)( + const struct upb_MiniTableExtension* e) { + return e->UPB_PRIVATE(sub).UPB_PRIVATE(submsg); +} + +UPB_INLINE void UPB_PRIVATE(_upb_MiniTableExtension_SetSubMessage)( + struct upb_MiniTableExtension* e, const struct upb_MiniTable* m) { + e->UPB_PRIVATE(sub).UPB_PRIVATE(submsg) = m; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif /* UPB_MINI_TABLE_INTERNAL_EXTENSION_H_ */ +// Must be last. + typedef struct upb_MiniTableExtension upb_MiniTableExtension; +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE const struct upb_MiniTableField* upb_MiniTableExtension_AsField( + const upb_MiniTableExtension* e) { + return UPB_PRIVATE(_upb_MiniTableExtension_AsField)(e); +} + +UPB_API_INLINE uint32_t +upb_MiniTableExtension_Number(const upb_MiniTableExtension* e) { + return UPB_PRIVATE(_upb_MiniTableExtension_Number)(e); +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableExtension_GetSubMessage( + const upb_MiniTableExtension* e) { + return UPB_PRIVATE(_upb_MiniTableExtension_GetSubMessage)(e); +} + +UPB_API_INLINE void upb_MiniTableExtension_SetSubMessage( + upb_MiniTableExtension* e, const struct upb_MiniTable* m) { + return UPB_PRIVATE(_upb_MiniTableExtension_SetSubMessage)(e, m); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + #endif /* UPB_MINI_TABLE_EXTENSION_H_ */ // Must be last. @@ -1989,80 +2358,6 @@ typedef struct { #endif // UPB_MINI_TABLE_INTERNAL_TYPES_H_ -#ifndef UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ -#define UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ - - -// Must be last. - -#ifdef __cplusplus -extern "C" { -#endif - -/* Extension registry: a dynamic data structure that stores a map of: - * (upb_MiniTable, number) -> extension info - * - * upb_decode() uses upb_ExtensionRegistry to look up extensions while parsing - * binary format. - * - * upb_ExtensionRegistry is part of the mini-table (msglayout) family of - * objects. Like all mini-table objects, it is suitable for reflection-less - * builds that do not want to expose names into the binary. - * - * Unlike most mini-table types, upb_ExtensionRegistry requires dynamic memory - * allocation and dynamic initialization: - * * If reflection is being used, then upb_DefPool will construct an appropriate - * upb_ExtensionRegistry automatically. - * * For a mini-table only build, the user must manually construct the - * upb_ExtensionRegistry and populate it with all of the extensions the user - * cares about. - * * A third alternative is to manually unpack relevant extensions after the - * main parse is complete, similar to how Any works. This is perhaps the - * nicest solution from the perspective of reducing dependencies, avoiding - * dynamic memory allocation, and avoiding the need to parse uninteresting - * extensions. The downsides are: - * (1) parse errors are not caught during the main parse - * (2) the CPU hit of parsing comes during access, which could cause an - * undesirable stutter in application performance. - * - * Users cannot directly get or put into this map. Users can only add the - * extensions from a generated module and pass the extension registry to the - * binary decoder. - * - * A upb_DefPool provides a upb_ExtensionRegistry, so any users who use - * reflection do not need to populate a upb_ExtensionRegistry directly. - */ - -typedef struct upb_ExtensionRegistry upb_ExtensionRegistry; - -// Creates a upb_ExtensionRegistry in the given arena. -// The arena must outlive any use of the extreg. -UPB_API upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena); - -UPB_API bool upb_ExtensionRegistry_Add(upb_ExtensionRegistry* r, - const upb_MiniTableExtension* e); - -// Adds the given extension info for the array |e| of size |count| into the -// registry. If there are any errors, the entire array is backed out. -// The extensions must outlive the registry. -// Possible errors include OOM or an extension number that already exists. -// TODO: There is currently no way to know the exact reason for failure. -bool upb_ExtensionRegistry_AddArray(upb_ExtensionRegistry* r, - const upb_MiniTableExtension** e, - size_t count); - -// Looks up the extension (if any) defined for message type |t| and field -// number |num|. Returns the extension if found, otherwise NULL. -UPB_API const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup( - const upb_ExtensionRegistry* r, const upb_MiniTable* t, uint32_t num); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ */ - // Must be last. #ifdef __cplusplus @@ -2102,11 +2397,8 @@ struct upb_Message_InternalData { * char data[size - sizeof(upb_Message_InternalData)]; */ }; -/* Maps upb_CType -> memory size. */ -extern char _upb_CTypeo_size[12]; - -UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* t) { - return t->size + sizeof(upb_Message_Internal); +UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* m) { + return m->UPB_PRIVATE(size) + sizeof(upb_Message_Internal); } // Inline version upb_Message_New(), for internal use. @@ -2131,8 +2423,11 @@ void _upb_Message_DiscardUnknown_shallow(upb_Message* msg); // Adds unknown data (serialized protobuf data) to the given message. // The data is copied into the message instance. -bool _upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len, - upb_Arena* arena); +bool UPB_PRIVATE(_upb_Message_AddUnknown)(upb_Message* msg, const char* data, + size_t len, upb_Arena* arena); + +bool UPB_PRIVATE(_upb_Message_Realloc)(upb_Message* msg, size_t need, + upb_Arena* arena); #ifdef __cplusplus } /* extern "C" */ @@ -2169,60 +2464,48 @@ extern "C" { // Hasbit access /////////////////////////////////////////////////////////////// -UPB_INLINE size_t _upb_hasbit_ofs(size_t idx) { return idx / 8; } - -UPB_INLINE char _upb_hasbit_mask(size_t idx) { return 1 << (idx % 8); } - -UPB_INLINE bool _upb_hasbit(const upb_Message* msg, size_t idx) { - return (*UPB_PTR_AT(msg, _upb_hasbit_ofs(idx), const char) & - _upb_hasbit_mask(idx)) != 0; +UPB_INLINE bool UPB_PRIVATE(_upb_Message_GetHasbit)( + const upb_Message* msg, const upb_MiniTableField* f) { + const size_t offset = _upb_MiniTableField_HasbitOffset(f); + const char mask = _upb_MiniTableField_HasbitMask(f); + return (*UPB_PTR_AT(msg, offset, const char) & mask) != 0; } -UPB_INLINE void _upb_sethas(const upb_Message* msg, size_t idx) { - (*UPB_PTR_AT(msg, _upb_hasbit_ofs(idx), char)) |= _upb_hasbit_mask(idx); +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetHasbit)( + const upb_Message* msg, const upb_MiniTableField* f) { + const size_t offset = _upb_MiniTableField_HasbitOffset(f); + const char mask = _upb_MiniTableField_HasbitMask(f); + (*UPB_PTR_AT(msg, offset, char)) |= mask; } -UPB_INLINE void _upb_clearhas(const upb_Message* msg, size_t idx) { - (*UPB_PTR_AT(msg, _upb_hasbit_ofs(idx), char)) &= ~_upb_hasbit_mask(idx); -} - -UPB_INLINE size_t _upb_Message_Hasidx(const upb_MiniTableField* f) { - UPB_ASSERT(f->presence > 0); - return f->presence; -} - -UPB_INLINE bool _upb_hasbit_field(const upb_Message* msg, - const upb_MiniTableField* f) { - return _upb_hasbit(msg, _upb_Message_Hasidx(f)); -} - -UPB_INLINE void _upb_sethas_field(const upb_Message* msg, - const upb_MiniTableField* f) { - _upb_sethas(msg, _upb_Message_Hasidx(f)); +UPB_INLINE void UPB_PRIVATE(_upb_Message_ClearHasbit)( + const upb_Message* msg, const upb_MiniTableField* f) { + const size_t offset = _upb_MiniTableField_HasbitOffset(f); + const char mask = _upb_MiniTableField_HasbitMask(f); + (*UPB_PTR_AT(msg, offset, char)) &= ~mask; } // Oneof case access /////////////////////////////////////////////////////////// -UPB_INLINE size_t _upb_oneofcase_ofs(const upb_MiniTableField* f) { - UPB_ASSERT(f->presence < 0); - return ~(ptrdiff_t)f->presence; +UPB_INLINE uint32_t* UPB_PRIVATE(_upb_Message_OneofCasePtr)( + upb_Message* msg, const upb_MiniTableField* f) { + return UPB_PTR_AT(msg, _upb_MiniTableField_OneofOffset(f), uint32_t); } -UPB_INLINE uint32_t* _upb_oneofcase_field(upb_Message* msg, - const upb_MiniTableField* f) { - return UPB_PTR_AT(msg, _upb_oneofcase_ofs(f), uint32_t); +UPB_INLINE uint32_t UPB_PRIVATE(_upb_Message_GetOneofCase)( + const upb_Message* msg, const upb_MiniTableField* f) { + return *UPB_PRIVATE(_upb_Message_OneofCasePtr)((upb_Message*)msg, f); } -UPB_INLINE uint32_t _upb_getoneofcase_field(const upb_Message* msg, - const upb_MiniTableField* f) { - return *_upb_oneofcase_field((upb_Message*)msg, f); +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetOneofCase)( + upb_Message* msg, const upb_MiniTableField* f) { + *UPB_PRIVATE(_upb_Message_OneofCasePtr)(msg, f) = + upb_MiniTableField_Number(f); } -// LINT.ThenChange(GoogleInternalName2) +// TODO: implement _upb_Message_ClearOneofCase() -UPB_INLINE bool _upb_MiniTableField_InOneOf(const upb_MiniTableField* field) { - return field->presence < 0; -} +// LINT.ThenChange(GoogleInternalName2) UPB_INLINE void* _upb_MiniTableField_GetPtr(upb_Message* msg, const upb_MiniTableField* field) { @@ -2234,36 +2517,42 @@ UPB_INLINE const void* _upb_MiniTableField_GetConstPtr( return (char*)msg + field->offset; } -UPB_INLINE void _upb_Message_SetPresence(upb_Message* msg, - const upb_MiniTableField* field) { +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetPresence)( + upb_Message* msg, const upb_MiniTableField* field) { if (field->presence > 0) { - _upb_sethas_field(msg, field); - } else if (_upb_MiniTableField_InOneOf(field)) { - *_upb_oneofcase_field(msg, field) = field->number; + UPB_PRIVATE(_upb_Message_SetHasbit)(msg, field); + } else if (upb_MiniTableField_IsInOneof(field)) { + UPB_PRIVATE(_upb_Message_SetOneofCase)(msg, field); } } -UPB_INLINE bool _upb_MiniTable_ValueIsNonZero(const void* default_val, - const upb_MiniTableField* field) { - char zero[16] = {0}; - switch (_upb_MiniTableField_GetRep(field)) { +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_DataEquals)( + const upb_MiniTableField* field, const void* a, const void* b) { + switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(field)) { case kUpb_FieldRep_1Byte: - return memcmp(&zero, default_val, 1) != 0; + return memcmp(a, b, 1) == 0; case kUpb_FieldRep_4Byte: - return memcmp(&zero, default_val, 4) != 0; + return memcmp(a, b, 4) == 0; case kUpb_FieldRep_8Byte: - return memcmp(&zero, default_val, 8) != 0; + return memcmp(a, b, 8) == 0; case kUpb_FieldRep_StringView: { - const upb_StringView* sv = (const upb_StringView*)default_val; - return sv->size != 0; + const upb_StringView sa = *(const upb_StringView*)a; + const upb_StringView sb = *(const upb_StringView*)b; + return upb_StringView_IsEqual(sa, sb); } } UPB_UNREACHABLE(); } -UPB_INLINE void _upb_MiniTable_CopyFieldData(void* to, const void* from, - const upb_MiniTableField* field) { - switch (_upb_MiniTableField_GetRep(field)) { +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_DataIsZero)( + const upb_MiniTableField* field, const void* val) { + const char zero[16] = {0}; + return UPB_PRIVATE(_upb_MiniTableField_DataEquals)(field, val, zero); +} + +UPB_INLINE void UPB_PRIVATE(_upb_MiniTableField_DataCopy)( + const upb_MiniTableField* field, void* to, const void* from) { + switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(field)) { case kUpb_FieldRep_1Byte: memcpy(to, from, 1); return; @@ -2281,32 +2570,6 @@ UPB_INLINE void _upb_MiniTable_CopyFieldData(void* to, const void* from, UPB_UNREACHABLE(); } -UPB_INLINE size_t -_upb_MiniTable_ElementSizeLg2(const upb_MiniTableField* field) { - const unsigned char table[] = { - 0, - 3, // kUpb_FieldType_Double = 1, - 2, // kUpb_FieldType_Float = 2, - 3, // kUpb_FieldType_Int64 = 3, - 3, // kUpb_FieldType_UInt64 = 4, - 2, // kUpb_FieldType_Int32 = 5, - 3, // kUpb_FieldType_Fixed64 = 6, - 2, // kUpb_FieldType_Fixed32 = 7, - 0, // kUpb_FieldType_Bool = 8, - UPB_SIZE(3, 4), // kUpb_FieldType_String = 9, - UPB_SIZE(2, 3), // kUpb_FieldType_Group = 10, - UPB_SIZE(2, 3), // kUpb_FieldType_Message = 11, - UPB_SIZE(3, 4), // kUpb_FieldType_Bytes = 12, - 2, // kUpb_FieldType_UInt32 = 13, - 2, // kUpb_FieldType_Enum = 14, - 2, // kUpb_FieldType_SFixed32 = 15, - 3, // kUpb_FieldType_SFixed64 = 16, - 2, // kUpb_FieldType_SInt32 = 17, - 3, // kUpb_FieldType_SInt64 = 18, - }; - return table[field->UPB_PRIVATE(descriptortype)]; -} - // Here we define universal getter/setter functions for message fields. // These look very branchy and inefficient, but as long as the MiniTableField // values are known at compile time, all the branches are optimized away and @@ -2325,9 +2588,10 @@ _upb_MiniTable_ElementSizeLg2(const upb_MiniTableField* field) { // const upb_MiniTableField* field, // bool value, upb_Arena* a) { // UPB_ASSUME(field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bool); -// UPB_ASSUME(!upb_IsRepeatedOrMap(field)); -// UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_1Byte); -// _upb_Message_SetField(msg, field, &value, a); +// UPB_ASSUME(upb_MiniTableField_IsScalar(field)); +// UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == +// kUpb_FieldRep_1Byte); +// upb_Message_SetField(msg, field, &value, a); // } // // As a result, we can use these universal getters/setters for *all* message @@ -2341,7 +2605,7 @@ _upb_MiniTable_ElementSizeLg2(const upb_MiniTableField* field) { UPB_INLINE bool _upb_Message_HasExtensionField( const upb_Message* msg, const upb_MiniTableExtension* ext) { - UPB_ASSERT(upb_MiniTableField_HasPresence(&ext->field)); + UPB_ASSERT(upb_MiniTableField_HasPresence(&ext->UPB_PRIVATE(field))); return _upb_Message_Getext(msg, ext) != NULL; } @@ -2349,10 +2613,11 @@ UPB_INLINE bool _upb_Message_HasNonExtensionField( const upb_Message* msg, const upb_MiniTableField* field) { UPB_ASSERT(upb_MiniTableField_HasPresence(field)); UPB_ASSUME(!upb_MiniTableField_IsExtension(field)); - if (_upb_MiniTableField_InOneOf(field)) { - return _upb_getoneofcase_field(msg, field) == field->number; + if (upb_MiniTableField_IsInOneof(field)) { + return UPB_PRIVATE(_upb_Message_GetOneofCase)(msg, field) == + upb_MiniTableField_Number(field); } else { - return _upb_hasbit_field(msg, field); + return UPB_PRIVATE(_upb_Message_GetHasbit)(msg, field); } } @@ -2360,45 +2625,63 @@ static UPB_FORCEINLINE void _upb_Message_GetNonExtensionField( const upb_Message* msg, const upb_MiniTableField* field, const void* default_val, void* val) { UPB_ASSUME(!upb_MiniTableField_IsExtension(field)); - if ((_upb_MiniTableField_InOneOf(field) || - _upb_MiniTable_ValueIsNonZero(default_val, field)) && + if ((upb_MiniTableField_IsInOneof(field) || + !UPB_PRIVATE(_upb_MiniTableField_DataIsZero)(field, default_val)) && !_upb_Message_HasNonExtensionField(msg, field)) { - _upb_MiniTable_CopyFieldData(val, default_val, field); + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(field, val, default_val); return; } - _upb_MiniTable_CopyFieldData(val, _upb_MiniTableField_GetConstPtr(msg, field), - field); + UPB_PRIVATE(_upb_MiniTableField_DataCopy) + (field, val, _upb_MiniTableField_GetConstPtr(msg, field)); } UPB_INLINE void _upb_Message_GetExtensionField( const upb_Message* msg, const upb_MiniTableExtension* mt_ext, const void* default_val, void* val) { - UPB_ASSUME(upb_MiniTableField_IsExtension(&mt_ext->field)); const upb_Message_Extension* ext = _upb_Message_Getext(msg, mt_ext); + const upb_MiniTableField* f = &mt_ext->UPB_PRIVATE(field); + UPB_ASSUME(upb_MiniTableField_IsExtension(f)); + if (ext) { - _upb_MiniTable_CopyFieldData(val, &ext->data, &mt_ext->field); + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f, val, &ext->data); } else { - _upb_MiniTable_CopyFieldData(val, default_val, &mt_ext->field); + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f, val, default_val); } } -UPB_INLINE void _upb_Message_GetField(const upb_Message* msg, - const upb_MiniTableField* field, - const void* default_val, void* val) { +// Gets a mutable Array, Map or Message field. +// NOTE: For repeated/map fields, the resulting upb_Array*/upb_Map* can +// be NULL if a upb_Array/upb_Map has not been allocated yet. Array/map +// fields do not have presence, so this is semantically identical to a +// pointer to an empty array/map, and must be treated the same for all +// semantic purposes. +// +// For message fields, the pointer is guaranteed to be NULL iff the field +// is unset (as message fields do have presence). +UPB_INLINE upb_MutableMessageValue _upb_Message_GetMutableField( + const upb_Message* msg, const upb_MiniTableField* field) { + UPB_ASSUME(!upb_MiniTableField_IsScalar(field) || + upb_MiniTableField_IsSubMessage(field)); + + upb_MutableMessageValue default_val; + default_val.msg = NULL; + + upb_MutableMessageValue ret; if (upb_MiniTableField_IsExtension(field)) { _upb_Message_GetExtensionField(msg, (upb_MiniTableExtension*)field, - default_val, val); + &default_val, &ret); } else { - _upb_Message_GetNonExtensionField(msg, field, default_val, val); + _upb_Message_GetNonExtensionField(msg, field, &default_val, &ret); } + return ret; } UPB_INLINE void _upb_Message_SetNonExtensionField( upb_Message* msg, const upb_MiniTableField* field, const void* val) { UPB_ASSUME(!upb_MiniTableField_IsExtension(field)); - _upb_Message_SetPresence(msg, field); - _upb_MiniTable_CopyFieldData(_upb_MiniTableField_GetPtr(msg, field), val, - field); + UPB_PRIVATE(_upb_Message_SetPresence)(msg, field); + UPB_PRIVATE(_upb_MiniTableField_DataCopy) + (field, _upb_MiniTableField_GetPtr(msg, field), val); } UPB_INLINE bool _upb_Message_SetExtensionField( @@ -2408,22 +2691,11 @@ UPB_INLINE bool _upb_Message_SetExtensionField( upb_Message_Extension* ext = _upb_Message_GetOrCreateExtension(msg, mt_ext, a); if (!ext) return false; - _upb_MiniTable_CopyFieldData(&ext->data, val, &mt_ext->field); + UPB_PRIVATE(_upb_MiniTableField_DataCopy) + (&mt_ext->UPB_PRIVATE(field), &ext->data, val); return true; } -UPB_INLINE bool _upb_Message_SetField(upb_Message* msg, - const upb_MiniTableField* field, - const void* val, upb_Arena* a) { - if (upb_MiniTableField_IsExtension(field)) { - const upb_MiniTableExtension* ext = (const upb_MiniTableExtension*)field; - return _upb_Message_SetExtensionField(msg, ext, val, a); - } else { - _upb_Message_SetNonExtensionField(msg, field, val); - return true; - } -} - UPB_INLINE void _upb_Message_ClearExtensionField( upb_Message* msg, const upb_MiniTableExtension* ext_l) { upb_Message_Internal* in = upb_Message_Getinternal(msg); @@ -2441,21 +2713,21 @@ UPB_INLINE void _upb_Message_ClearExtensionField( UPB_INLINE void _upb_Message_ClearNonExtensionField( upb_Message* msg, const upb_MiniTableField* field) { if (field->presence > 0) { - _upb_clearhas(msg, _upb_Message_Hasidx(field)); - } else if (_upb_MiniTableField_InOneOf(field)) { - uint32_t* oneof_case = _upb_oneofcase_field(msg, field); - if (*oneof_case != field->number) return; - *oneof_case = 0; + UPB_PRIVATE(_upb_Message_ClearHasbit)(msg, field); + } else if (upb_MiniTableField_IsInOneof(field)) { + uint32_t* ptr = UPB_PRIVATE(_upb_Message_OneofCasePtr)(msg, field); + if (*ptr != upb_MiniTableField_Number(field)) return; + *ptr = 0; } const char zeros[16] = {0}; - _upb_MiniTable_CopyFieldData(_upb_MiniTableField_GetPtr(msg, field), zeros, - field); + UPB_PRIVATE(_upb_MiniTableField_DataCopy) + (field, _upb_MiniTableField_GetPtr(msg, field), zeros); } UPB_INLINE void _upb_Message_AssertMapIsUntagged( const upb_Message* msg, const upb_MiniTableField* field) { UPB_UNUSED(msg); - _upb_MiniTableField_CheckIsMap(field); + UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(field); #ifndef NDEBUG upb_TaggedMessagePtr default_val = 0; upb_TaggedMessagePtr tagged; @@ -2467,7 +2739,7 @@ UPB_INLINE void _upb_Message_AssertMapIsUntagged( UPB_INLINE upb_Map* _upb_Message_GetOrCreateMutableMap( upb_Message* msg, const upb_MiniTableField* field, size_t key_size, size_t val_size, upb_Arena* arena) { - _upb_MiniTableField_CheckIsMap(field); + UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(field); _upb_Message_AssertMapIsUntagged(msg, field); upb_Map* map = NULL; upb_Map* default_map_value = NULL; @@ -2475,7 +2747,7 @@ UPB_INLINE upb_Map* _upb_Message_GetOrCreateMutableMap( if (!map) { map = _upb_Map_New(arena, key_size, val_size); // Check again due to: https://godbolt.org/z/7WfaoKG1r - _upb_MiniTableField_CheckIsMap(field); + UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(field); _upb_Message_SetNonExtensionField(msg, field, &map); } return map; @@ -2500,6 +2772,10 @@ UPB_INLINE upb_Map* _upb_Message_GetOrCreateMutableMap( // Must be last. +#define _UPB_ARRAY_MASK_IMM 0x4 // Frozen/immutable bit. +#define _UPB_ARRAY_MASK_LG2 0x3 // Encoded elem size. +#define _UPB_ARRAY_MASK_ALL (_UPB_ARRAY_MASK_IMM | _UPB_ARRAY_MASK_LG2) + #ifdef __cplusplus extern "C" { #endif @@ -2507,97 +2783,148 @@ extern "C" { // LINT.IfChange(struct_definition) // Our internal representation for repeated fields. struct upb_Array { - uintptr_t data; /* Tagged ptr: low 3 bits of ptr are lg2(elem size). */ - size_t size; /* The number of elements in the array. */ - size_t capacity; /* Allocated storage. Measured in elements. */ + // This is a tagged pointer. Bits #0 and #1 encode the elem size as follows: + // 0 maps to elem size 1 + // 1 maps to elem size 4 + // 2 maps to elem size 8 + // 3 maps to elem size 16 + // + // Bit #2 contains the frozen/immutable flag (currently unimplemented). + uintptr_t data; + + size_t size; // The number of elements in the array. + size_t UPB_PRIVATE(capacity); // Allocated storage. Measured in elements. }; -// LINT.ThenChange(GoogleInternalName1) - -UPB_INLINE size_t _upb_Array_ElementSizeLg2(const upb_Array* arr) { - size_t ret = arr->data & 7; - UPB_ASSERT(ret <= 4); - return ret; -} -UPB_INLINE const void* _upb_array_constptr(const upb_Array* arr) { - _upb_Array_ElementSizeLg2(arr); // Check assertion. - return (void*)(arr->data & ~(uintptr_t)7); +UPB_INLINE void UPB_PRIVATE(_upb_Array_SetTaggedPtr)(upb_Array* array, + void* data, size_t lg2) { + UPB_ASSERT(lg2 != 1); + UPB_ASSERT(lg2 <= 4); + const size_t bits = lg2 - (lg2 != 0); + array->data = (uintptr_t)data | bits; } -UPB_INLINE uintptr_t _upb_array_tagptr(void* ptr, int elem_size_lg2) { - UPB_ASSERT(elem_size_lg2 <= 4); - return (uintptr_t)ptr | elem_size_lg2; -} - -UPB_INLINE void* _upb_array_ptr(upb_Array* arr) { - return (void*)_upb_array_constptr(arr); +UPB_INLINE size_t UPB_PRIVATE(_upb_Array_ElemSizeLg2)(const upb_Array* array) { + const size_t bits = array->data & _UPB_ARRAY_MASK_LG2; + const size_t lg2 = bits + (bits != 0); + return lg2; } -UPB_INLINE uintptr_t _upb_tag_arrptr(void* ptr, int elem_size_lg2) { - UPB_ASSERT(elem_size_lg2 <= 4); - UPB_ASSERT(((uintptr_t)ptr & 7) == 0); - return (uintptr_t)ptr | (unsigned)elem_size_lg2; +UPB_INLINE const void* _upb_array_constptr(const upb_Array* array) { + UPB_PRIVATE(_upb_Array_ElemSizeLg2)(array); // Check assertions. + return (void*)(array->data & ~(uintptr_t)_UPB_ARRAY_MASK_ALL); } -extern const char _upb_Array_CTypeSizeLg2Table[]; - -UPB_INLINE size_t _upb_Array_CTypeSizeLg2(upb_CType ctype) { - return _upb_Array_CTypeSizeLg2Table[ctype]; +UPB_INLINE void* _upb_array_ptr(upb_Array* array) { + return (void*)_upb_array_constptr(array); } -UPB_INLINE upb_Array* _upb_Array_New(upb_Arena* a, size_t init_capacity, - int elem_size_lg2) { +UPB_INLINE upb_Array* UPB_PRIVATE(_upb_Array_New)(upb_Arena* arena, + size_t init_capacity, + int elem_size_lg2) { + UPB_ASSERT(elem_size_lg2 != 1); UPB_ASSERT(elem_size_lg2 <= 4); - const size_t arr_size = UPB_ALIGN_UP(sizeof(upb_Array), UPB_MALLOC_ALIGN); - const size_t bytes = arr_size + (init_capacity << elem_size_lg2); - upb_Array* arr = (upb_Array*)upb_Arena_Malloc(a, bytes); - if (!arr) return NULL; - arr->data = _upb_tag_arrptr(UPB_PTR_AT(arr, arr_size, void), elem_size_lg2); - arr->size = 0; - arr->capacity = init_capacity; - return arr; + const size_t array_size = UPB_ALIGN_UP(sizeof(upb_Array), UPB_MALLOC_ALIGN); + const size_t bytes = array_size + (init_capacity << elem_size_lg2); + upb_Array* array = (upb_Array*)upb_Arena_Malloc(arena, bytes); + if (!array) return NULL; + UPB_PRIVATE(_upb_Array_SetTaggedPtr) + (array, UPB_PTR_AT(array, array_size, void), elem_size_lg2); + array->size = 0; + array->UPB_PRIVATE(capacity) = init_capacity; + return array; } // Resizes the capacity of the array to be at least min_size. -bool _upb_array_realloc(upb_Array* arr, size_t min_size, upb_Arena* arena); +bool UPB_PRIVATE(_upb_Array_Realloc)(upb_Array* array, size_t min_size, + upb_Arena* arena); -UPB_INLINE bool _upb_array_reserve(upb_Array* arr, size_t size, - upb_Arena* arena) { - if (arr->capacity < size) return _upb_array_realloc(arr, size, arena); +UPB_INLINE bool UPB_PRIVATE(_upb_Array_Reserve)(upb_Array* array, size_t size, + upb_Arena* arena) { + if (array->UPB_PRIVATE(capacity) < size) + return UPB_PRIVATE(_upb_Array_Realloc)(array, size, arena); return true; } // Resize without initializing new elements. -UPB_INLINE bool _upb_Array_ResizeUninitialized(upb_Array* arr, size_t size, +UPB_INLINE bool _upb_Array_ResizeUninitialized(upb_Array* array, size_t size, upb_Arena* arena) { - UPB_ASSERT(size <= arr->size || arena); // Allow NULL arena when shrinking. - if (!_upb_array_reserve(arr, size, arena)) return false; - arr->size = size; + UPB_ASSERT(size <= array->size || arena); // Allow NULL arena when shrinking. + if (!UPB_PRIVATE(_upb_Array_Reserve)(array, size, arena)) return false; + array->size = size; return true; } // This function is intended for situations where elem_size is compile-time // constant or a known expression of the form (1 << lg2), so that the expression // i*elem_size does not result in an actual multiplication. -UPB_INLINE void _upb_Array_Set(upb_Array* arr, size_t i, const void* data, - size_t elem_size) { - UPB_ASSERT(i < arr->size); - UPB_ASSERT(elem_size == 1U << _upb_Array_ElementSizeLg2(arr)); - char* arr_data = (char*)_upb_array_ptr(arr); +UPB_INLINE void UPB_PRIVATE(_upb_Array_Set)(upb_Array* array, size_t i, + const void* data, + size_t elem_size) { + UPB_ASSERT(i < array->size); + UPB_ASSERT(elem_size == 1U << UPB_PRIVATE(_upb_Array_ElemSizeLg2)(array)); + char* arr_data = (char*)_upb_array_ptr(array); memcpy(arr_data + (i * elem_size), data, elem_size); } -UPB_INLINE void _upb_array_detach(const void* msg, size_t ofs) { - *UPB_PTR_AT(msg, ofs, upb_Array*) = NULL; -} +// LINT.ThenChange( +// GoogleInternalName1, +//) #ifdef __cplusplus } /* extern "C" */ #endif +#undef _UPB_ARRAY_MASK_IMM +#undef _UPB_ARRAY_MASK_LG2 +#undef _UPB_ARRAY_MASK_ALL + #endif /* UPB_MESSAGE_INTERNAL_ARRAY_H_ */ +#ifndef UPB_MINI_TABLE_SUB_H_ +#define UPB_MINI_TABLE_SUB_H_ + + +// Must be last. + +typedef union upb_MiniTableSub upb_MiniTableSub; + +#ifdef __cplusplus +extern "C" { +#endif + +// Constructors + +UPB_API_INLINE upb_MiniTableSub +upb_MiniTableSub_FromEnum(const struct upb_MiniTableEnum* subenum) { + return UPB_PRIVATE(_upb_MiniTableSub_FromEnum)(subenum); +} + +UPB_API_INLINE upb_MiniTableSub +upb_MiniTableSub_FromMessage(const struct upb_MiniTable* submsg) { + return UPB_PRIVATE(_upb_MiniTableSub_FromMessage)(submsg); +} + +// Getters + +UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTableSub_Enum( + upb_MiniTableSub sub) { + return UPB_PRIVATE(_upb_MiniTableSub_Enum)(sub); +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableSub_Message( + upb_MiniTableSub sub) { + return UPB_PRIVATE(_upb_MiniTableSub_Message)(sub); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_SUB_H_ */ + // Must be last. #ifdef __cplusplus @@ -2633,28 +2960,62 @@ UPB_API_INLINE bool upb_Message_HasField(const upb_Message* msg, UPB_API_INLINE uint32_t upb_Message_WhichOneofFieldNumber( const upb_Message* message, const upb_MiniTableField* oneof_field) { - UPB_ASSUME(_upb_MiniTableField_InOneOf(oneof_field)); - return _upb_getoneofcase_field(message, oneof_field); + UPB_ASSUME(upb_MiniTableField_IsInOneof(oneof_field)); + return UPB_PRIVATE(_upb_Message_GetOneofCase)(message, oneof_field); +} + +// NOTE: The default_val is only used for fields that support presence. +// For repeated/map fields, the resulting upb_Array*/upb_Map* can be NULL if a +// upb_Array/upb_Map has not been allocated yet. Array/map fields do not have +// presence, so this is semantically identical to a pointer to an empty +// array/map, and must be treated the same for all semantic purposes. +UPB_INLINE upb_MessageValue +upb_Message_GetField(const upb_Message* msg, const upb_MiniTableField* field, + upb_MessageValue default_val) { + upb_MessageValue ret; + if (upb_MiniTableField_IsExtension(field)) { + _upb_Message_GetExtensionField(msg, (upb_MiniTableExtension*)field, + &default_val, &ret); + } else { + _upb_Message_GetNonExtensionField(msg, field, &default_val, &ret); + } + return ret; +} + +UPB_INLINE bool upb_Message_SetField(upb_Message* msg, + const upb_MiniTableField* field, + upb_MessageValue val, upb_Arena* a) { + if (upb_MiniTableField_IsExtension(field)) { + const upb_MiniTableExtension* ext = (const upb_MiniTableExtension*)field; + return _upb_Message_SetExtensionField(msg, ext, &val, a); + } else { + _upb_Message_SetNonExtensionField(msg, field, &val); + return true; + } } UPB_API_INLINE bool upb_Message_GetBool(const upb_Message* msg, const upb_MiniTableField* field, bool default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Bool); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_1Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - bool ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_1Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue def; + def.bool_val = default_val; + return upb_Message_GetField(msg, field, def).bool_val; } UPB_API_INLINE bool upb_Message_SetBool(upb_Message* msg, const upb_MiniTableField* field, bool value, upb_Arena* a) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Bool); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_1Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_1Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue val; + val.bool_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE int32_t upb_Message_GetInt32(const upb_Message* msg, @@ -2662,11 +3023,13 @@ UPB_API_INLINE int32_t upb_Message_GetInt32(const upb_Message* msg, int32_t default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Int32 || upb_MiniTableField_CType(field) == kUpb_CType_Enum); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - int32_t ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_4Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + + upb_MessageValue def; + def.int32_val = default_val; + return upb_Message_GetField(msg, field, def).int32_val; } UPB_API_INLINE bool upb_Message_SetInt32(upb_Message* msg, @@ -2674,37 +3037,46 @@ UPB_API_INLINE bool upb_Message_SetInt32(upb_Message* msg, int32_t value, upb_Arena* a) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Int32 || upb_MiniTableField_CType(field) == kUpb_CType_Enum); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_4Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue val; + val.int32_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE uint32_t upb_Message_GetUInt32(const upb_Message* msg, const upb_MiniTableField* field, uint32_t default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt32); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - uint32_t ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_4Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + + upb_MessageValue def; + def.uint32_val = default_val; + return upb_Message_GetField(msg, field, def).uint32_val; } UPB_API_INLINE bool upb_Message_SetUInt32(upb_Message* msg, const upb_MiniTableField* field, uint32_t value, upb_Arena* a) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt32); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_4Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue val; + val.uint32_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE void upb_Message_SetClosedEnum( upb_Message* msg, const upb_MiniTable* msg_mini_table, const upb_MiniTableField* field, int32_t value) { UPB_ASSERT(upb_MiniTableField_IsClosedEnum(field)); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_4Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); UPB_ASSERT(upb_MiniTableEnum_CheckValue( upb_MiniTable_GetSubEnumTable(msg_mini_table, field), value)); _upb_Message_SetNonExtensionField(msg, field, &value); @@ -2712,94 +3084,116 @@ UPB_API_INLINE void upb_Message_SetClosedEnum( UPB_API_INLINE int64_t upb_Message_GetInt64(const upb_Message* msg, const upb_MiniTableField* field, - uint64_t default_val) { + int64_t default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Int64); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - int64_t ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_8Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + + upb_MessageValue def; + def.int64_val = default_val; + return upb_Message_GetField(msg, field, def).int64_val; } UPB_API_INLINE bool upb_Message_SetInt64(upb_Message* msg, const upb_MiniTableField* field, int64_t value, upb_Arena* a) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Int64); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_8Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue val; + val.int64_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE uint64_t upb_Message_GetUInt64(const upb_Message* msg, const upb_MiniTableField* field, uint64_t default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt64); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - uint64_t ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_8Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + + upb_MessageValue def; + def.uint64_val = default_val; + return upb_Message_GetField(msg, field, def).uint64_val; } UPB_API_INLINE bool upb_Message_SetUInt64(upb_Message* msg, const upb_MiniTableField* field, uint64_t value, upb_Arena* a) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt64); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_8Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue val; + val.uint64_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE float upb_Message_GetFloat(const upb_Message* msg, const upb_MiniTableField* field, float default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Float); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - float ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_4Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + + upb_MessageValue def; + def.float_val = default_val; + return upb_Message_GetField(msg, field, def).float_val; } UPB_API_INLINE bool upb_Message_SetFloat(upb_Message* msg, const upb_MiniTableField* field, float value, upb_Arena* a) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Float); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_4Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue val; + val.float_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE double upb_Message_GetDouble(const upb_Message* msg, const upb_MiniTableField* field, double default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Double); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - double ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_8Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + + upb_MessageValue def; + def.double_val = default_val; + return upb_Message_GetField(msg, field, def).double_val; } UPB_API_INLINE bool upb_Message_SetDouble(upb_Message* msg, const upb_MiniTableField* field, double value, upb_Arena* a) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Double); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_8Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue val; + val.double_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE upb_StringView upb_Message_GetString(const upb_Message* msg, const upb_MiniTableField* field, - upb_StringView def_val) { + upb_StringView default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_String || upb_MiniTableField_CType(field) == kUpb_CType_Bytes); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_StringView); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - upb_StringView ret; - _upb_Message_GetField(msg, field, &def_val, &ret); - return ret; + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_StringView); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + + upb_MessageValue def; + def.str_val = default_val; + return upb_Message_GetField(msg, field, def).str_val; } UPB_API_INLINE bool upb_Message_SetString(upb_Message* msg, @@ -2807,18 +3201,21 @@ UPB_API_INLINE bool upb_Message_SetString(upb_Message* msg, upb_StringView value, upb_Arena* a) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_String || upb_MiniTableField_CType(field) == kUpb_CType_Bytes); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_StringView); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_StringView); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue val; + val.str_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE upb_TaggedMessagePtr upb_Message_GetTaggedMessagePtr( const upb_Message* msg, const upb_MiniTableField* field, upb_Message* default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Message); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); upb_TaggedMessagePtr tagged; _upb_Message_GetNonExtensionField(msg, field, &default_val, &tagged); return tagged; @@ -2839,10 +3236,11 @@ UPB_API_INLINE void _upb_Message_SetTaggedMessagePtr( upb_Message* msg, const upb_MiniTable* mini_table, const upb_MiniTableField* field, upb_TaggedMessagePtr sub_message) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Message); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - UPB_ASSERT(mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + UPB_ASSERT(upb_MiniTableSub_Message( + mini_table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)])); _upb_Message_SetNonExtensionField(msg, field, &sub_message); } @@ -2861,19 +3259,19 @@ UPB_API_INLINE upb_Message* upb_Message_GetOrCreateMutableMessage( UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Message); upb_Message* sub_message = *UPB_PTR_AT(msg, field->offset, upb_Message*); if (!sub_message) { - const upb_MiniTable* sub_mini_table = - mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* sub_mini_table = upb_MiniTableSub_Message( + mini_table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]); UPB_ASSERT(sub_mini_table); sub_message = _upb_Message_New(sub_mini_table, arena); *UPB_PTR_AT(msg, field->offset, upb_Message*) = sub_message; - _upb_Message_SetPresence(msg, field); + UPB_PRIVATE(_upb_Message_SetPresence)(msg, field); } return sub_message; } UPB_API_INLINE const upb_Array* upb_Message_GetArray( const upb_Message* msg, const upb_MiniTableField* field) { - _upb_MiniTableField_CheckIsArray(field); + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(field); upb_Array* ret; const upb_Array* default_val = NULL; _upb_Message_GetNonExtensionField(msg, field, &default_val, &ret); @@ -2882,20 +3280,23 @@ UPB_API_INLINE const upb_Array* upb_Message_GetArray( UPB_API_INLINE upb_Array* upb_Message_GetMutableArray( upb_Message* msg, const upb_MiniTableField* field) { - _upb_MiniTableField_CheckIsArray(field); + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(field); return (upb_Array*)upb_Message_GetArray(msg, field); } UPB_API_INLINE upb_Array* upb_Message_GetOrCreateMutableArray( upb_Message* msg, const upb_MiniTableField* field, upb_Arena* arena) { UPB_ASSERT(arena); - _upb_MiniTableField_CheckIsArray(field); + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(field); upb_Array* array = upb_Message_GetMutableArray(msg, field); if (!array) { - array = _upb_Array_New(arena, 4, _upb_MiniTable_ElementSizeLg2(field)); + array = UPB_PRIVATE(_upb_Array_New)( + arena, 4, UPB_PRIVATE(_upb_MiniTableField_ElemSizeLg2)(field)); // Check again due to: https://godbolt.org/z/7WfaoKG1r - _upb_MiniTableField_CheckIsArray(field); - _upb_Message_SetField(msg, field, &array, arena); + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(field); + upb_MessageValue val; + val.array_val = array; + upb_Message_SetField(msg, field, val, arena); } return array; } @@ -2903,7 +3304,7 @@ UPB_API_INLINE upb_Array* upb_Message_GetOrCreateMutableArray( UPB_API_INLINE void* upb_Message_ResizeArrayUninitialized( upb_Message* msg, const upb_MiniTableField* field, size_t size, upb_Arena* arena) { - _upb_MiniTableField_CheckIsArray(field); + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(field); upb_Array* arr = upb_Message_GetOrCreateMutableArray(msg, field, arena); if (!arr || !_upb_Array_ResizeUninitialized(arr, size, arena)) return NULL; return _upb_array_ptr(arr); @@ -2911,7 +3312,7 @@ UPB_API_INLINE void* upb_Message_ResizeArrayUninitialized( UPB_API_INLINE const upb_Map* upb_Message_GetMap( const upb_Message* msg, const upb_MiniTableField* field) { - _upb_MiniTableField_CheckIsMap(field); + UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(field); _upb_Message_AssertMapIsUntagged(msg, field); upb_Map* ret; const upb_Map* default_val = NULL; @@ -2929,9 +3330,9 @@ UPB_API_INLINE upb_Map* upb_Message_GetOrCreateMutableMap( const upb_MiniTableField* field, upb_Arena* arena) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Message); const upb_MiniTableField* map_entry_key_field = - &map_entry_mini_table->fields[0]; + &map_entry_mini_table->UPB_PRIVATE(fields)[0]; const upb_MiniTableField* map_entry_value_field = - &map_entry_mini_table->fields[1]; + &map_entry_mini_table->UPB_PRIVATE(fields)[1]; return _upb_Message_GetOrCreateMutableMap( msg, field, _upb_Map_CTypeSize(upb_MiniTableField_CType(map_entry_key_field)), @@ -3010,14 +3411,6 @@ UPB_INLINE void _upb_msg_map_set_value(void* msg, const void* val, #define UPB_MINI_TABLE_DECODE_H_ -#ifndef UPB_MINI_TABLE_SUB_H_ -#define UPB_MINI_TABLE_SUB_H_ - - -typedef union upb_MiniTableSub upb_MiniTableSub; - -#endif /* UPB_MINI_TABLE_INTERNAL_SUB_H_ */ - // Export the newer headers, for legacy users. New users should include the // more specific headers directly. // IWYU pragma: begin_exports @@ -3177,8 +3570,7 @@ UPB_API upb_MiniTableExtension* _upb_MiniTableExtension_Build( UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_Build( const char* data, size_t len, const upb_MiniTable* extendee, upb_Arena* arena, upb_Status* status) { - upb_MiniTableSub sub; - sub.submsg = NULL; + upb_MiniTableSub sub = upb_MiniTableSub_FromMessage(NULL); return _upb_MiniTableExtension_Build( data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status); } @@ -3186,8 +3578,7 @@ UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_Build( UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_BuildMessage( const char* data, size_t len, const upb_MiniTable* extendee, upb_MiniTable* submsg, upb_Arena* arena, upb_Status* status) { - upb_MiniTableSub sub; - sub.submsg = submsg; + upb_MiniTableSub sub = upb_MiniTableSub_FromMessage(submsg); return _upb_MiniTableExtension_Build( data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status); } @@ -3195,8 +3586,7 @@ UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_BuildMessage( UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_BuildEnum( const char* data, size_t len, const upb_MiniTable* extendee, upb_MiniTableEnum* subenum, upb_Arena* arena, upb_Status* status) { - upb_MiniTableSub sub; - sub.subenum = subenum; + upb_MiniTableSub sub = upb_MiniTableSub_FromEnum(subenum); return _upb_MiniTableExtension_Build( data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status); } @@ -3219,6 +3609,80 @@ upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len, #endif /* UPB_MINI_TABLE_DECODE_H_ */ +#ifndef UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ +#define UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +/* Extension registry: a dynamic data structure that stores a map of: + * (upb_MiniTable, number) -> extension info + * + * upb_decode() uses upb_ExtensionRegistry to look up extensions while parsing + * binary format. + * + * upb_ExtensionRegistry is part of the mini-table (msglayout) family of + * objects. Like all mini-table objects, it is suitable for reflection-less + * builds that do not want to expose names into the binary. + * + * Unlike most mini-table types, upb_ExtensionRegistry requires dynamic memory + * allocation and dynamic initialization: + * * If reflection is being used, then upb_DefPool will construct an appropriate + * upb_ExtensionRegistry automatically. + * * For a mini-table only build, the user must manually construct the + * upb_ExtensionRegistry and populate it with all of the extensions the user + * cares about. + * * A third alternative is to manually unpack relevant extensions after the + * main parse is complete, similar to how Any works. This is perhaps the + * nicest solution from the perspective of reducing dependencies, avoiding + * dynamic memory allocation, and avoiding the need to parse uninteresting + * extensions. The downsides are: + * (1) parse errors are not caught during the main parse + * (2) the CPU hit of parsing comes during access, which could cause an + * undesirable stutter in application performance. + * + * Users cannot directly get or put into this map. Users can only add the + * extensions from a generated module and pass the extension registry to the + * binary decoder. + * + * A upb_DefPool provides a upb_ExtensionRegistry, so any users who use + * reflection do not need to populate a upb_ExtensionRegistry directly. + */ + +typedef struct upb_ExtensionRegistry upb_ExtensionRegistry; + +// Creates a upb_ExtensionRegistry in the given arena. +// The arena must outlive any use of the extreg. +UPB_API upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena); + +UPB_API bool upb_ExtensionRegistry_Add(upb_ExtensionRegistry* r, + const upb_MiniTableExtension* e); + +// Adds the given extension info for the array |e| of size |count| into the +// registry. If there are any errors, the entire array is backed out. +// The extensions must outlive the registry. +// Possible errors include OOM or an extension number that already exists. +// TODO: There is currently no way to know the exact reason for failure. +bool upb_ExtensionRegistry_AddArray(upb_ExtensionRegistry* r, + const upb_MiniTableExtension** e, + size_t count); + +// Looks up the extension (if any) defined for message type |t| and field +// number |num|. Returns the extension if found, otherwise NULL. +UPB_API const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup( + const upb_ExtensionRegistry* r, const upb_MiniTable* t, uint32_t num); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ */ + #ifndef UPB_MINI_TABLE_FILE_H_ #define UPB_MINI_TABLE_FILE_H_ @@ -3226,23 +3690,102 @@ upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len, #ifndef UPB_MINI_TABLE_INTERNAL_FILE_H_ #define UPB_MINI_TABLE_INTERNAL_FILE_H_ - // Must be last. struct upb_MiniTableFile { - const struct upb_MiniTable** msgs; - const struct upb_MiniTableEnum** enums; - const struct upb_MiniTableExtension** exts; - int msg_count; - int enum_count; - int ext_count; + const struct upb_MiniTable** UPB_PRIVATE(msgs); + const struct upb_MiniTableEnum** UPB_PRIVATE(enums); + const struct upb_MiniTableExtension** UPB_PRIVATE(exts); + int UPB_PRIVATE(msg_count); + int UPB_PRIVATE(enum_count); + int UPB_PRIVATE(ext_count); }; +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE int UPB_PRIVATE(_upb_MiniTableFile_EnumCount)( + const struct upb_MiniTableFile* f) { + return f->UPB_PRIVATE(enum_count); +} + +UPB_INLINE int UPB_PRIVATE(_upb_MiniTableFile_ExtensionCount)( + const struct upb_MiniTableFile* f) { + return f->UPB_PRIVATE(ext_count); +} + +UPB_INLINE int UPB_PRIVATE(_upb_MiniTableFile_MessageCount)( + const struct upb_MiniTableFile* f) { + return f->UPB_PRIVATE(msg_count); +} + +UPB_INLINE const struct upb_MiniTableEnum* UPB_PRIVATE(_upb_MiniTableFile_Enum)( + const struct upb_MiniTableFile* f, int i) { + UPB_ASSERT(i < f->UPB_PRIVATE(enum_count)); + return f->UPB_PRIVATE(enums)[i]; +} + +UPB_INLINE const struct upb_MiniTableExtension* UPB_PRIVATE( + _upb_MiniTableFile_Extension)(const struct upb_MiniTableFile* f, int i) { + UPB_ASSERT(i < f->UPB_PRIVATE(ext_count)); + return f->UPB_PRIVATE(exts)[i]; +} + +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTableFile_Message)( + const struct upb_MiniTableFile* f, int i) { + UPB_ASSERT(i < f->UPB_PRIVATE(msg_count)); + return f->UPB_PRIVATE(msgs)[i]; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif /* UPB_MINI_TABLE_INTERNAL_FILE_H_ */ typedef struct upb_MiniTableFile upb_MiniTableFile; +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTableFile_Enum( + const upb_MiniTableFile* f, int i) { + return UPB_PRIVATE(_upb_MiniTableFile_Enum)(f, i); +} + +UPB_API_INLINE int upb_MiniTableFile_EnumCount(const upb_MiniTableFile* f) { + return UPB_PRIVATE(_upb_MiniTableFile_EnumCount)(f); +} + +UPB_API_INLINE const struct upb_MiniTableExtension* upb_MiniTableFile_Extension( + const upb_MiniTableFile* f, int i) { + return UPB_PRIVATE(_upb_MiniTableFile_Extension)(f, i); +} + +UPB_API_INLINE int upb_MiniTableFile_ExtensionCount( + const upb_MiniTableFile* f) { + return UPB_PRIVATE(_upb_MiniTableFile_ExtensionCount)(f); +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableFile_Message( + const upb_MiniTableFile* f, int i) { + return UPB_PRIVATE(_upb_MiniTableFile_Message)(f, i); +} + +UPB_API_INLINE int upb_MiniTableFile_MessageCount(const upb_MiniTableFile* f) { + return UPB_PRIVATE(_upb_MiniTableFile_MessageCount)(f); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + #endif /* UPB_MINI_TABLE_FILE_H_ */ // upb_decode: parsing into a upb_Message using a upb_MiniTable. @@ -3734,7 +4277,8 @@ typedef enum { google_protobuf_EDITION_2023 = 1000, google_protobuf_EDITION_99997_TEST_ONLY = 99997, google_protobuf_EDITION_99998_TEST_ONLY = 99998, - google_protobuf_EDITION_99999_TEST_ONLY = 99999 + google_protobuf_EDITION_99999_TEST_ONLY = 99999, + google_protobuf_EDITION_MAX = 2147483647 } google_protobuf_Edition; typedef enum { @@ -3775,8 +4319,8 @@ typedef enum { typedef enum { google_protobuf_FeatureSet_UTF8_VALIDATION_UNKNOWN = 0, - google_protobuf_FeatureSet_NONE = 1, - google_protobuf_FeatureSet_VERIFY = 2 + google_protobuf_FeatureSet_VERIFY = 2, + google_protobuf_FeatureSet_NONE = 3 } google_protobuf_FeatureSet_Utf8Validation; typedef enum { @@ -3953,7 +4497,7 @@ UPB_INLINE struct google_protobuf_FileDescriptorProto* google_protobuf_FileDescr } struct google_protobuf_FileDescriptorProto* sub = (struct google_protobuf_FileDescriptorProto*)_upb_Message_New(&google__protobuf__FileDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -4371,7 +4915,7 @@ UPB_INLINE bool google_protobuf_FileDescriptorProto_add_dependency(google_protob if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_mutable_message_type(google_protobuf_FileDescriptorProto* msg, size_t* size) { @@ -4397,7 +4941,7 @@ UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_FileDescripto } struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)_upb_Message_New(&google__protobuf__DescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_mutable_enum_type(google_protobuf_FileDescriptorProto* msg, size_t* size) { @@ -4423,7 +4967,7 @@ UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_FileDescr } struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)_upb_Message_New(&google__protobuf__EnumDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_mutable_service(google_protobuf_FileDescriptorProto* msg, size_t* size) { @@ -4449,7 +4993,7 @@ UPB_INLINE struct google_protobuf_ServiceDescriptorProto* google_protobuf_FileDe } struct google_protobuf_ServiceDescriptorProto* sub = (struct google_protobuf_ServiceDescriptorProto*)_upb_Message_New(&google__protobuf__ServiceDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_mutable_extension(google_protobuf_FileDescriptorProto* msg, size_t* size) { @@ -4475,7 +5019,7 @@ UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_FileDesc } struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_Message_New(&google__protobuf__FieldDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE void google_protobuf_FileDescriptorProto_set_options(google_protobuf_FileDescriptorProto *msg, google_protobuf_FileOptions* value) { @@ -4523,7 +5067,7 @@ UPB_INLINE bool google_protobuf_FileDescriptorProto_add_public_dependency(google if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_weak_dependency(google_protobuf_FileDescriptorProto* msg, size_t* size) { @@ -4547,7 +5091,7 @@ UPB_INLINE bool google_protobuf_FileDescriptorProto_add_weak_dependency(google_p if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto *msg, upb_StringView value) { @@ -4948,7 +5492,7 @@ UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_Descript } struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_Message_New(&google__protobuf__FieldDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_mutable_nested_type(google_protobuf_DescriptorProto* msg, size_t* size) { @@ -4974,7 +5518,7 @@ UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_DescriptorPro } struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)_upb_Message_New(&google__protobuf__DescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_mutable_enum_type(google_protobuf_DescriptorProto* msg, size_t* size) { @@ -5000,7 +5544,7 @@ UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_Descripto } struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)_upb_Message_New(&google__protobuf__EnumDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_mutable_extension_range(google_protobuf_DescriptorProto* msg, size_t* size) { @@ -5026,7 +5570,7 @@ UPB_INLINE struct google_protobuf_DescriptorProto_ExtensionRange* google_protobu } struct google_protobuf_DescriptorProto_ExtensionRange* sub = (struct google_protobuf_DescriptorProto_ExtensionRange*)_upb_Message_New(&google__protobuf__DescriptorProto__ExtensionRange_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_mutable_extension(google_protobuf_DescriptorProto* msg, size_t* size) { @@ -5052,7 +5596,7 @@ UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_Descript } struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_Message_New(&google__protobuf__FieldDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE void google_protobuf_DescriptorProto_set_options(google_protobuf_DescriptorProto *msg, google_protobuf_MessageOptions* value) { @@ -5090,7 +5634,7 @@ UPB_INLINE struct google_protobuf_OneofDescriptorProto* google_protobuf_Descript } struct google_protobuf_OneofDescriptorProto* sub = (struct google_protobuf_OneofDescriptorProto*)_upb_Message_New(&google__protobuf__OneofDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_mutable_reserved_range(google_protobuf_DescriptorProto* msg, size_t* size) { @@ -5116,7 +5660,7 @@ UPB_INLINE struct google_protobuf_DescriptorProto_ReservedRange* google_protobuf } struct google_protobuf_DescriptorProto_ReservedRange* sub = (struct google_protobuf_DescriptorProto_ReservedRange*)_upb_Message_New(&google__protobuf__DescriptorProto__ReservedRange_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE upb_StringView* google_protobuf_DescriptorProto_mutable_reserved_name(google_protobuf_DescriptorProto* msg, size_t* size) { @@ -5140,7 +5684,7 @@ UPB_INLINE bool google_protobuf_DescriptorProto_add_reserved_name(google_protobu if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } @@ -5484,7 +6028,7 @@ UPB_INLINE struct google_protobuf_ExtensionRangeOptions_Declaration* google_prot } struct google_protobuf_ExtensionRangeOptions_Declaration* sub = (struct google_protobuf_ExtensionRangeOptions_Declaration*)_upb_Message_New(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE void google_protobuf_ExtensionRangeOptions_set_verification(google_protobuf_ExtensionRangeOptions *msg, int32_t value) { @@ -5526,7 +6070,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_Extension } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -6203,7 +6747,7 @@ UPB_INLINE struct google_protobuf_EnumValueDescriptorProto* google_protobuf_Enum } struct google_protobuf_EnumValueDescriptorProto* sub = (struct google_protobuf_EnumValueDescriptorProto*)_upb_Message_New(&google__protobuf__EnumValueDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE void google_protobuf_EnumDescriptorProto_set_options(google_protobuf_EnumDescriptorProto *msg, google_protobuf_EnumOptions* value) { @@ -6241,7 +6785,7 @@ UPB_INLINE struct google_protobuf_EnumDescriptorProto_EnumReservedRange* google_ } struct google_protobuf_EnumDescriptorProto_EnumReservedRange* sub = (struct google_protobuf_EnumDescriptorProto_EnumReservedRange*)_upb_Message_New(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE upb_StringView* google_protobuf_EnumDescriptorProto_mutable_reserved_name(google_protobuf_EnumDescriptorProto* msg, size_t* size) { @@ -6265,7 +6809,7 @@ UPB_INLINE bool google_protobuf_EnumDescriptorProto_add_reserved_name(google_pro if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } @@ -6576,7 +7120,7 @@ UPB_INLINE struct google_protobuf_MethodDescriptorProto* google_protobuf_Service } struct google_protobuf_MethodDescriptorProto* sub = (struct google_protobuf_MethodDescriptorProto*)_upb_Message_New(&google__protobuf__MethodDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_options(google_protobuf_ServiceDescriptorProto *msg, google_protobuf_ServiceOptions* value) { @@ -7254,7 +7798,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FileOptio } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -7476,7 +8020,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MessageOp } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -7834,7 +8378,7 @@ UPB_INLINE bool google_protobuf_FieldOptions_add_targets(google_protobuf_FieldOp if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } UPB_INLINE google_protobuf_FieldOptions_EditionDefault** google_protobuf_FieldOptions_mutable_edition_defaults(google_protobuf_FieldOptions* msg, size_t* size) { @@ -7860,7 +8404,7 @@ UPB_INLINE struct google_protobuf_FieldOptions_EditionDefault* google_protobuf_F } struct google_protobuf_FieldOptions_EditionDefault* sub = (struct google_protobuf_FieldOptions_EditionDefault*)_upb_Message_New(&google__protobuf__FieldOptions__EditionDefault_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE void google_protobuf_FieldOptions_set_features(google_protobuf_FieldOptions *msg, google_protobuf_FeatureSet* value) { @@ -7898,7 +8442,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOpti } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -8100,7 +8644,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_OneofOpti } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -8284,7 +8828,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumOptio } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -8449,7 +8993,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumValue } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -8595,7 +9139,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ServiceOp } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -8760,7 +9304,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MethodOpt } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -8950,7 +9494,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption_NamePart* google_protobuf_ } struct google_protobuf_UninterpretedOption_NamePart* sub = (struct google_protobuf_UninterpretedOption_NamePart*)_upb_Message_New(&google__protobuf__UninterpretedOption__NamePart_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE void google_protobuf_UninterpretedOption_set_identifier_value(google_protobuf_UninterpretedOption *msg, upb_StringView value) { @@ -9330,7 +9874,7 @@ UPB_INLINE struct google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* g } struct google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* sub = (struct google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault*)_upb_Message_New(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE void google_protobuf_FeatureSetDefaults_set_minimum_edition(google_protobuf_FeatureSetDefaults *msg, int32_t value) { @@ -9521,7 +10065,7 @@ UPB_INLINE struct google_protobuf_SourceCodeInfo_Location* google_protobuf_Sourc } struct google_protobuf_SourceCodeInfo_Location* sub = (struct google_protobuf_SourceCodeInfo_Location*)_upb_Message_New(&google__protobuf__SourceCodeInfo__Location_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -9723,7 +10267,7 @@ UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_path(google_protobuf if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_span(google_protobuf_SourceCodeInfo_Location* msg, size_t* size) { @@ -9747,7 +10291,7 @@ UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_span(google_protobuf if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_StringView value) { @@ -9779,7 +10323,7 @@ UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_leading_detached_com if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } @@ -9879,7 +10423,7 @@ UPB_INLINE struct google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_ } struct google_protobuf_GeneratedCodeInfo_Annotation* sub = (struct google_protobuf_GeneratedCodeInfo_Annotation*)_upb_Message_New(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -10037,7 +10581,7 @@ UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_add_path(google_pro if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_StringView value) { @@ -10156,6 +10700,14 @@ UPB_API void upb_DefPool_Free(upb_DefPool* s); UPB_API upb_DefPool* upb_DefPool_New(void); +UPB_API const UPB_DESC(FeatureSetDefaults) * + upb_DefPool_FeatureSetDefaults(const upb_DefPool* s); + +UPB_API bool upb_DefPool_SetFeatureSetDefaults(upb_DefPool* s, + const char* serialized_defaults, + size_t serialized_len, + upb_Status* status); + UPB_API const upb_MessageDef* upb_DefPool_FindMessageByName( const upb_DefPool* s, const char* sym); @@ -10178,7 +10730,7 @@ const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s, const upb_FieldDef* upb_DefPool_FindExtensionByMiniTable( const upb_DefPool* s, const upb_MiniTableExtension* ext); -const upb_FieldDef* upb_DefPool_FindExtensionByName(const upb_DefPool* s, +UPB_API const upb_FieldDef* upb_DefPool_FindExtensionByName(const upb_DefPool* s, const char* sym); const upb_FieldDef* upb_DefPool_FindExtensionByNameWithSize( @@ -10201,7 +10753,7 @@ UPB_API const upb_FileDef* upb_DefPool_AddFile( upb_DefPool* s, const UPB_DESC(FileDescriptorProto) * file_proto, upb_Status* status); -const upb_ExtensionRegistry* upb_DefPool_ExtensionRegistry( +UPB_API const upb_ExtensionRegistry* upb_DefPool_ExtensionRegistry( const upb_DefPool* s); const upb_FieldDef** upb_DefPool_GetAllExtensions(const upb_DefPool* s, @@ -10247,6 +10799,7 @@ bool upb_EnumDef_MiniDescriptorEncode(const upb_EnumDef* e, upb_Arena* a, const char* upb_EnumDef_Name(const upb_EnumDef* e); const UPB_DESC(EnumOptions) * upb_EnumDef_Options(const upb_EnumDef* e); +const UPB_DESC(FeatureSet) * upb_EnumDef_ResolvedFeatures(const upb_EnumDef* e); upb_StringView upb_EnumDef_ReservedName(const upb_EnumDef* e, int i); int upb_EnumDef_ReservedNameCount(const upb_EnumDef* e); @@ -10285,6 +10838,8 @@ UPB_API const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v); UPB_API int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* v); const UPB_DESC(EnumValueOptions) * upb_EnumValueDef_Options(const upb_EnumValueDef* v); +const UPB_DESC(FeatureSet) * + upb_EnumValueDef_ResolvedFeatures(const upb_EnumValueDef* e); #ifdef __cplusplus } /* extern "C" */ @@ -10311,6 +10866,8 @@ int32_t upb_ExtensionRange_End(const upb_ExtensionRange* r); bool upb_ExtensionRange_HasOptions(const upb_ExtensionRange* r); const UPB_DESC(ExtensionRangeOptions) * upb_ExtensionRange_Options(const upb_ExtensionRange* r); +const UPB_DESC(FeatureSet) * + upb_ExtensionRange_ResolvedFeatures(const upb_ExtensionRange* e); #ifdef __cplusplus } /* extern "C" */ @@ -10372,6 +10929,8 @@ const upb_MiniTableField* upb_FieldDef_MiniTable(const upb_FieldDef* f); UPB_API const char* upb_FieldDef_Name(const upb_FieldDef* f); UPB_API uint32_t upb_FieldDef_Number(const upb_FieldDef* f); const UPB_DESC(FieldOptions) * upb_FieldDef_Options(const upb_FieldDef* f); +const UPB_DESC(FeatureSet) * + upb_FieldDef_ResolvedFeatures(const upb_FieldDef* f); UPB_API const upb_OneofDef* upb_FieldDef_RealContainingOneof( const upb_FieldDef* f); UPB_API upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f); @@ -10395,11 +10954,14 @@ UPB_API upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f); extern "C" { #endif +UPB_API const char* upb_FileDef_EditionName(int edition); + const upb_FileDef* upb_FileDef_Dependency(const upb_FileDef* f, int i); int upb_FileDef_DependencyCount(const upb_FileDef* f); bool upb_FileDef_HasOptions(const upb_FileDef* f); UPB_API const char* upb_FileDef_Name(const upb_FileDef* f); const UPB_DESC(FileOptions) * upb_FileDef_Options(const upb_FileDef* f); +const UPB_DESC(FeatureSet) * upb_FileDef_ResolvedFeatures(const upb_FileDef* f); const char* upb_FileDef_Package(const upb_FileDef* f); UPB_DESC(Edition) upb_FileDef_Edition(const upb_FileDef* f); UPB_API const upb_DefPool* upb_FileDef_Pool(const upb_FileDef* f); @@ -10559,6 +11121,8 @@ int upb_MessageDef_RealOneofCount(const upb_MessageDef* m); const UPB_DESC(MessageOptions) * upb_MessageDef_Options(const upb_MessageDef* m); +const UPB_DESC(FeatureSet) * + upb_MessageDef_ResolvedFeatures(const upb_MessageDef* m); upb_StringView upb_MessageDef_ReservedName(const upb_MessageDef* m, int i); int upb_MessageDef_ReservedNameCount(const upb_MessageDef* m); @@ -10596,6 +11160,8 @@ int upb_MethodDef_Index(const upb_MethodDef* m); const upb_MessageDef* upb_MethodDef_InputType(const upb_MethodDef* m); const char* upb_MethodDef_Name(const upb_MethodDef* m); const UPB_DESC(MethodOptions) * upb_MethodDef_Options(const upb_MethodDef* m); +const UPB_DESC(FeatureSet) * + upb_MethodDef_ResolvedFeatures(const upb_MethodDef* m); const upb_MessageDef* upb_MethodDef_OutputType(const upb_MethodDef* m); bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m); const upb_ServiceDef* upb_MethodDef_Service(const upb_MethodDef* m); @@ -10636,7 +11202,9 @@ const upb_FieldDef* upb_OneofDef_LookupNumber(const upb_OneofDef* o, uint32_t num); UPB_API const char* upb_OneofDef_Name(const upb_OneofDef* o); int upb_OneofDef_numfields(const upb_OneofDef* o); -const UPB_DESC(OneofOptions) * upb_OneofDef_Options(const upb_OneofDef* o); +const UPB_DESC(OneofOptions*) upb_OneofDef_Options(const upb_OneofDef* o); +const UPB_DESC(FeatureSet*) + upb_OneofDef_ResolvedFeatures(const upb_OneofDef* o); #ifdef __cplusplus } /* extern "C" */ @@ -10668,6 +11236,8 @@ int upb_ServiceDef_MethodCount(const upb_ServiceDef* s); const char* upb_ServiceDef_Name(const upb_ServiceDef* s); const UPB_DESC(ServiceOptions) * upb_ServiceDef_Options(const upb_ServiceDef* s); +const UPB_DESC(FeatureSet) * + upb_ServiceDef_ResolvedFeatures(const upb_ServiceDef* s); #ifdef __cplusplus } /* extern "C" */ @@ -10735,12 +11305,11 @@ bool _upb_DefPool_LoadDefInitEx(upb_DefPool* s, const _upb_DefPool_Init* init, #endif /* UPB_REFLECTION_DEF_POOL_INTERNAL_H_ */ + #ifdef __cplusplus extern "C" { #endif - - extern _upb_DefPool_Init google_protobuf_descriptor_proto_upbdefinit; UPB_INLINE const upb_MessageDef *google_protobuf_FileDescriptorSet_getmsgdef(upb_DefPool *s) { @@ -11701,6 +12270,7 @@ double _upb_NoLocaleStrtod(const char *str, char **endptr); typedef struct _upb_MemBlock _upb_MemBlock; +// LINT.IfChange(struct_definition) struct upb_Arena { _upb_ArenaHead head; @@ -11729,6 +12299,7 @@ struct upb_Arena { // upb_Arena_SpaceAllocated(). UPB_ATOMIC(_upb_MemBlock*) blocks; }; +// LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/arena.ts) UPB_INLINE bool _upb_Arena_IsTaggedRefcount(uintptr_t parent_or_count) { return (parent_or_count & 1) == 1; @@ -11853,14 +12424,9 @@ UPB_INLINE bool _upb_NonAtomic_CompareExchangeStrongP(void* addr, #endif // UPB_PORT_ATOMIC_H_ -#ifndef UPB_WIRE_READER_H_ -#define UPB_WIRE_READER_H_ - - -#ifndef UPB_WIRE_INTERNAL_SWAP_H_ -#define UPB_WIRE_INTERNAL_SWAP_H_ +#ifndef UPB_MESSAGE_COPY_H_ +#define UPB_MESSAGE_COPY_H_ -#include // Must be last. @@ -11868,238 +12434,38 @@ UPB_INLINE bool _upb_NonAtomic_CompareExchangeStrongP(void* addr, extern "C" { #endif -UPB_INLINE bool _upb_IsLittleEndian(void) { - int x = 1; - return *(char*)&x == 1; -} +// Deep clones a message using the provided target arena. +upb_Message* upb_Message_DeepClone(const upb_Message* msg, + const upb_MiniTable* m, upb_Arena* arena); -UPB_INLINE uint32_t _upb_BigEndian_Swap32(uint32_t val) { - if (_upb_IsLittleEndian()) return val; +// Shallow clones a message using the provided target arena. +upb_Message* upb_Message_ShallowClone(const upb_Message* msg, + const upb_MiniTable* m, upb_Arena* arena); - return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | - ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24); -} - -UPB_INLINE uint64_t _upb_BigEndian_Swap64(uint64_t val) { - if (_upb_IsLittleEndian()) return val; - - return ((uint64_t)_upb_BigEndian_Swap32((uint32_t)val) << 32) | - _upb_BigEndian_Swap32((uint32_t)(val >> 32)); -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_WIRE_INTERNAL_SWAP_H_ */ - -#ifndef UPB_WIRE_TYPES_H_ -#define UPB_WIRE_TYPES_H_ - -// A list of types as they are encoded on the wire. -typedef enum { - kUpb_WireType_Varint = 0, - kUpb_WireType_64Bit = 1, - kUpb_WireType_Delimited = 2, - kUpb_WireType_StartGroup = 3, - kUpb_WireType_EndGroup = 4, - kUpb_WireType_32Bit = 5 -} upb_WireType; - -#endif /* UPB_WIRE_TYPES_H_ */ - -// Must be last. - -#ifdef __cplusplus -extern "C" { -#endif - -// The upb_WireReader interface is suitable for general-purpose parsing of -// protobuf binary wire format. It is designed to be used along with -// upb_EpsCopyInputStream for buffering, and all parsing routines in this file -// assume that at least kUpb_EpsCopyInputStream_SlopBytes worth of data is -// available to read without any bounds checks. - -#define kUpb_WireReader_WireTypeMask 7 -#define kUpb_WireReader_WireTypeBits 3 - -typedef struct { - const char* ptr; - uint64_t val; -} _upb_WireReader_ReadLongVarintRet; - -_upb_WireReader_ReadLongVarintRet _upb_WireReader_ReadLongVarint( - const char* ptr, uint64_t val); - -static UPB_FORCEINLINE const char* _upb_WireReader_ReadVarint(const char* ptr, - uint64_t* val, - int maxlen, - uint64_t maxval) { - uint64_t byte = (uint8_t)*ptr; - if (UPB_LIKELY((byte & 0x80) == 0)) { - *val = (uint32_t)byte; - return ptr + 1; - } - const char* start = ptr; - _upb_WireReader_ReadLongVarintRet res = - _upb_WireReader_ReadLongVarint(ptr, byte); - if (!res.ptr || (maxlen < 10 && res.ptr - start > maxlen) || - res.val > maxval) { - return NULL; // Malformed. - } - *val = res.val; - return res.ptr; -} - -// Parses a tag into `tag`, and returns a pointer past the end of the tag, or -// NULL if there was an error in the tag data. -// -// REQUIRES: there must be at least 10 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -static UPB_FORCEINLINE const char* upb_WireReader_ReadTag(const char* ptr, - uint32_t* tag) { - uint64_t val; - ptr = _upb_WireReader_ReadVarint(ptr, &val, 5, UINT32_MAX); - if (!ptr) return NULL; - *tag = val; - return ptr; -} - -// Given a tag, returns the field number. -UPB_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag) { - return tag >> kUpb_WireReader_WireTypeBits; -} - -// Given a tag, returns the wire type. -UPB_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag) { - return tag & kUpb_WireReader_WireTypeMask; -} - -UPB_INLINE const char* upb_WireReader_ReadVarint(const char* ptr, - uint64_t* val) { - return _upb_WireReader_ReadVarint(ptr, val, 10, UINT64_MAX); -} - -// Skips data for a varint, returning a pointer past the end of the varint, or -// NULL if there was an error in the varint data. -// -// REQUIRES: there must be at least 10 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -UPB_INLINE const char* upb_WireReader_SkipVarint(const char* ptr) { - uint64_t val; - return upb_WireReader_ReadVarint(ptr, &val); -} - -// Reads a varint indicating the size of a delimited field into `size`, or -// NULL if there was an error in the varint data. -// -// REQUIRES: there must be at least 10 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -UPB_INLINE const char* upb_WireReader_ReadSize(const char* ptr, int* size) { - uint64_t size64; - ptr = upb_WireReader_ReadVarint(ptr, &size64); - if (!ptr || size64 >= INT32_MAX) return NULL; - *size = size64; - return ptr; -} +// Deep clones array contents. +upb_Array* upb_Array_DeepClone(const upb_Array* array, upb_CType value_type, + const upb_MiniTable* sub, upb_Arena* arena); -// Reads a fixed32 field, performing byte swapping if necessary. -// -// REQUIRES: there must be at least 4 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -UPB_INLINE const char* upb_WireReader_ReadFixed32(const char* ptr, void* val) { - uint32_t uval; - memcpy(&uval, ptr, 4); - uval = _upb_BigEndian_Swap32(uval); - memcpy(val, &uval, 4); - return ptr + 4; -} +// Deep clones map contents. +upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type, + upb_CType value_type, + const upb_MiniTable* map_entry_table, + upb_Arena* arena); -// Reads a fixed64 field, performing byte swapping if necessary. -// -// REQUIRES: there must be at least 4 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -UPB_INLINE const char* upb_WireReader_ReadFixed64(const char* ptr, void* val) { - uint64_t uval; - memcpy(&uval, ptr, 8); - uval = _upb_BigEndian_Swap64(uval); - memcpy(val, &uval, 8); - return ptr + 8; -} - -const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag, - int depth_limit, - upb_EpsCopyInputStream* stream); +// Deep copies the message from src to dst. +bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* m, upb_Arena* arena); -// Skips data for a group, returning a pointer past the end of the group, or -// NULL if there was an error parsing the group. The `tag` argument should be -// the start group tag that begins the group. The `depth_limit` argument -// indicates how many levels of recursion the group is allowed to have before -// reporting a parse error (this limit exists to protect against stack -// overflow). -// -// TODO: evaluate how the depth_limit should be specified. Do users need -// control over this? -UPB_INLINE const char* upb_WireReader_SkipGroup( - const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { - return _upb_WireReader_SkipGroup(ptr, tag, 100, stream); -} - -UPB_INLINE const char* _upb_WireReader_SkipValue( - const char* ptr, uint32_t tag, int depth_limit, - upb_EpsCopyInputStream* stream) { - switch (upb_WireReader_GetWireType(tag)) { - case kUpb_WireType_Varint: - return upb_WireReader_SkipVarint(ptr); - case kUpb_WireType_32Bit: - return ptr + 4; - case kUpb_WireType_64Bit: - return ptr + 8; - case kUpb_WireType_Delimited: { - int size; - ptr = upb_WireReader_ReadSize(ptr, &size); - if (!ptr) return NULL; - ptr += size; - return ptr; - } - case kUpb_WireType_StartGroup: - return _upb_WireReader_SkipGroup(ptr, tag, depth_limit, stream); - case kUpb_WireType_EndGroup: - return NULL; // Should be handled before now. - default: - return NULL; // Unknown wire type. - } -} - -// Skips data for a wire value of any type, returning a pointer past the end of -// the data, or NULL if there was an error parsing the group. The `tag` argument -// should be the tag that was just parsed. The `depth_limit` argument indicates -// how many levels of recursion a group is allowed to have before reporting a -// parse error (this limit exists to protect against stack overflow). -// -// REQUIRES: there must be at least 10 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -// -// TODO: evaluate how the depth_limit should be specified. Do users need -// control over this? -UPB_INLINE const char* upb_WireReader_SkipValue( - const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { - return _upb_WireReader_SkipValue(ptr, tag, 100, stream); -} +// Shallow copies the message from src to dst. +void upb_Message_ShallowCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* m); #ifdef __cplusplus } /* extern "C" */ #endif -#endif // UPB_WIRE_READER_H_ +#endif // UPB_MESSAGE_COPY_H_ // EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// @@ -12172,7 +12538,7 @@ UPB_INLINE void _upb_mapsorter_init(_upb_mapsorter* s) { } UPB_INLINE void _upb_mapsorter_destroy(_upb_mapsorter* s) { - if (s->entries) free(s->entries); + if (s->entries) upb_gfree(s->entries); } UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter* s, const upb_Map* map, @@ -12213,10 +12579,6 @@ bool _upb_mapsorter_pushexts(_upb_mapsorter* s, #endif /* UPB_COLLECTIONS_INTERNAL_MAP_SORTER_H_ */ -#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_ -#define UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_ - - #ifndef UPB_MINI_DESCRIPTOR_INTERNAL_BASE92_H_ #define UPB_MINI_DESCRIPTOR_INTERNAL_BASE92_H_ @@ -12271,6 +12633,10 @@ UPB_INLINE const char* _upb_Base92_DecodeVarint(const char* ptr, #endif // UPB_MINI_DESCRIPTOR_INTERNAL_BASE92_H_ +#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_ +#define UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_ + + // Must be last. // upb_MdDecoder: used internally for decoding MiniDescriptors for messages, @@ -12507,6 +12873,10 @@ extern "C" { struct upb_DefBuilder { upb_DefPool* symtab; + upb_strtable feature_cache; // Caches features by identity. + UPB_DESC(FeatureSet*) legacy_features; // For computing legacy features. + char* tmp_buf; // Temporary buffer in tmp_arena. + size_t tmp_buf_size; // Size of temporary buffer. upb_FileDef* file; // File we are building. upb_Arena* arena; // Allocate defs here. upb_Arena* tmp_arena; // For temporary allocations. @@ -12599,6 +12969,25 @@ UPB_INLINE void _upb_DefBuilder_CheckIdentFull(upb_DefBuilder* ctx, if (!good) _upb_DefBuilder_CheckIdentSlow(ctx, name, true); } +// Returns true if the returned feature set is new and must be populated. +bool _upb_DefBuilder_GetOrCreateFeatureSet(upb_DefBuilder* ctx, + const UPB_DESC(FeatureSet*) parent, + upb_StringView key, + UPB_DESC(FeatureSet**) set); + +const UPB_DESC(FeatureSet*) + _upb_DefBuilder_DoResolveFeatures(upb_DefBuilder* ctx, + const UPB_DESC(FeatureSet*) parent, + const UPB_DESC(FeatureSet*) child, + bool is_implicit); + +UPB_INLINE const UPB_DESC(FeatureSet*) + _upb_DefBuilder_ResolveFeatures(upb_DefBuilder* ctx, + const UPB_DESC(FeatureSet*) parent, + const UPB_DESC(FeatureSet*) child) { + return _upb_DefBuilder_DoResolveFeatures(ctx, parent, child, false); +} + #ifdef __cplusplus } /* extern "C" */ #endif @@ -12621,10 +13010,11 @@ bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a); const upb_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e); // Allocate and initialize an array of |n| enum defs. -upb_EnumDef* _upb_EnumDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(EnumDescriptorProto) * const* protos, - const upb_MessageDef* containing_type); +upb_EnumDef* _upb_EnumDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(EnumDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + const upb_MessageDef* containing_type); #ifdef __cplusplus } /* extern "C" */ @@ -12648,7 +13038,8 @@ upb_EnumValueDef* _upb_EnumValueDef_At(const upb_EnumValueDef* v, int i); // Allocate and initialize an array of |n| enum value defs owned by |e|. upb_EnumValueDef* _upb_EnumValueDefs_New( upb_DefBuilder* ctx, const char* prefix, int n, - const UPB_DESC(EnumValueDescriptorProto) * const* protos, upb_EnumDef* e, + const UPB_DESC(EnumValueDescriptorProto*) const* protos, + const UPB_DESC(FeatureSet*) parent_features, upb_EnumDef* e, bool* is_sorted); const upb_EnumValueDef** _upb_EnumValueDefs_Sorted(const upb_EnumValueDef* v, @@ -12685,16 +13076,19 @@ void _upb_FieldDef_BuildMiniTableExtension(upb_DefBuilder* ctx, const upb_FieldDef* f); // Allocate and initialize an array of |n| extensions (field defs). -upb_FieldDef* _upb_Extensions_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(FieldDescriptorProto) * const* protos, const char* prefix, - upb_MessageDef* m); +upb_FieldDef* _upb_Extensions_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(FieldDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + const char* prefix, upb_MessageDef* m); // Allocate and initialize an array of |n| field defs. -upb_FieldDef* _upb_FieldDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(FieldDescriptorProto) * const* protos, const char* prefix, - upb_MessageDef* m, bool* is_sorted); +upb_FieldDef* _upb_FieldDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(FieldDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + const char* prefix, upb_MessageDef* m, + bool* is_sorted); // Allocate and return a list of pointers to the |n| field defs in |ff|, // sorted by field number. @@ -12759,9 +13153,12 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx, void _upb_MessageDef_Resolve(upb_DefBuilder* ctx, upb_MessageDef* m); // Allocate and initialize an array of |n| message defs. -upb_MessageDef* _upb_MessageDefs_New( - upb_DefBuilder* ctx, int n, const UPB_DESC(DescriptorProto) * const* protos, - const upb_MessageDef* containing_type); +upb_MessageDef* _upb_MessageDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(DescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) + parent_features, + const upb_MessageDef* containing_type); #ifdef __cplusplus } /* extern "C" */ @@ -12783,9 +13180,11 @@ extern "C" { upb_ServiceDef* _upb_ServiceDef_At(const upb_ServiceDef* s, int i); // Allocate and initialize an array of |n| service defs. -upb_ServiceDef* _upb_ServiceDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(ServiceDescriptorProto) * const* protos); +upb_ServiceDef* _upb_ServiceDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(ServiceDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) + parent_features); #ifdef __cplusplus } /* extern "C" */ @@ -12794,6 +13193,20 @@ upb_ServiceDef* _upb_ServiceDefs_New( #endif /* UPB_REFLECTION_SERVICE_DEF_INTERNAL_H_ */ +#ifndef UPB_REFLECTION_UPB_EDITION_DEFAULTS_H_ +#define UPB_REFLECTION_UPB_EDITION_DEFAULTS_H_ + +// This file contains the serialized FeatureSetDefaults object for +// language-independent features and (possibly at some point) for upb-specific +// features. This is used for feature resolution under Editions. +// NOLINTBEGIN +// clang-format off +#define UPB_INTERNAL_UPB_EDITION_DEFAULTS "\n\021\022\014\010\001\020\002\030\002 \003(\0010\002\030\346\007\n\021\022\014\010\002\020\001\030\001 \002(\0010\001\030\347\007\n\021\022\014\010\001\020\001\030\001 \002(\0010\001\030\350\007 \346\007(\350\007" +// clang-format on +// NOLINTEND + +#endif // UPB_REFLECTION_UPB_EDITION_DEFAULTS_H_ + #ifndef UPB_REFLECTION_DESC_STATE_INTERNAL_H_ #define UPB_REFLECTION_DESC_STATE_INTERNAL_H_ @@ -12866,7 +13279,7 @@ upb_EnumReservedRange* _upb_EnumReservedRange_At(const upb_EnumReservedRange* r, // Allocate and initialize an array of |n| reserved ranges owned by |e|. upb_EnumReservedRange* _upb_EnumReservedRanges_New( upb_DefBuilder* ctx, int n, - const UPB_DESC(EnumDescriptorProto_EnumReservedRange) * const* protos, + const UPB_DESC(EnumDescriptorProto_EnumReservedRange*) const* protos, const upb_EnumDef* e); #ifdef __cplusplus @@ -12914,8 +13327,8 @@ upb_ExtensionRange* _upb_ExtensionRange_At(const upb_ExtensionRange* r, int i); // Allocate and initialize an array of |n| extension ranges owned by |m|. upb_ExtensionRange* _upb_ExtensionRanges_New( upb_DefBuilder* ctx, int n, - const UPB_DESC(DescriptorProto_ExtensionRange) * const* protos, - const upb_MessageDef* m); + const UPB_DESC(DescriptorProto_ExtensionRange*) const* protos, + const UPB_DESC(FeatureSet*) parent_features, const upb_MessageDef* m); #ifdef __cplusplus } /* extern "C" */ @@ -12939,9 +13352,11 @@ void _upb_OneofDef_Insert(upb_DefBuilder* ctx, upb_OneofDef* o, const upb_FieldDef* f, const char* name, size_t size); // Allocate and initialize an array of |n| oneof defs owned by |m|. -upb_OneofDef* _upb_OneofDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(OneofDescriptorProto) * const* protos, upb_MessageDef* m); +upb_OneofDef* _upb_OneofDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(OneofDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + upb_MessageDef* m); size_t _upb_OneofDefs_Finalize(upb_DefBuilder* ctx, upb_MessageDef* m); @@ -13013,9 +13428,11 @@ extern "C" { upb_MethodDef* _upb_MethodDef_At(const upb_MethodDef* m, int i); // Allocate and initialize an array of |n| method defs owned by |s|. -upb_MethodDef* _upb_MethodDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(MethodDescriptorProto) * const* protos, upb_ServiceDef* s); +upb_MethodDef* _upb_MethodDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(MethodDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + upb_ServiceDef* s); #ifdef __cplusplus } /* extern "C" */ @@ -13115,12 +13532,12 @@ non_ascii: const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, const upb_Message* msg, - const upb_MiniTable* l); + const upb_MiniTable* m); /* x86-64 pointers always have the high 16 bits matching. So we can shift * left 8 and right 8 without loss of information. */ UPB_INLINE intptr_t decode_totable(const upb_MiniTable* tablep) { - return ((intptr_t)tablep << 8) | tablep->table_mask; + return ((intptr_t)tablep << 8) | tablep->UPB_PRIVATE(table_mask); } UPB_INLINE const upb_MiniTable* decode_totablep(intptr_t table) { @@ -13141,8 +13558,8 @@ UPB_INLINE const char* _upb_Decoder_BufferFlipCallback( if (!old_end) _upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed); if (d->unknown) { - if (!_upb_Message_AddUnknown(d->unknown_msg, d->unknown, - old_end - d->unknown, &d->arena)) { + if (!UPB_PRIVATE(_upb_Message_AddUnknown)( + d->unknown_msg, d->unknown, old_end - d->unknown, &d->arena)) { _upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } d->unknown = new_start; @@ -13161,9 +13578,9 @@ const char* _upb_FastDecoder_TagDispatch(upb_Decoder* d, const char* ptr, size_t idx = tag & mask; UPB_ASSUME((idx & 7) == 0); idx >>= 3; - data = table_p->fasttable[idx].field_data ^ tag; - UPB_MUSTTAIL return table_p->fasttable[idx].field_parser(d, ptr, msg, table, - hasbits, data); + data = table_p->UPB_PRIVATE(fasttable)[idx].field_data ^ tag; + UPB_MUSTTAIL return table_p->UPB_PRIVATE(fasttable)[idx].field_parser( + d, ptr, msg, table, hasbits, data); } #endif @@ -13176,6 +13593,254 @@ UPB_INLINE uint32_t _upb_FastDecoder_LoadTag(const char* ptr) { #endif /* UPB_WIRE_INTERNAL_DECODE_H_ */ +#ifndef UPB_WIRE_INTERNAL_SWAP_H_ +#define UPB_WIRE_INTERNAL_SWAP_H_ + +#include + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE bool _upb_IsLittleEndian(void) { + int x = 1; + return *(char*)&x == 1; +} + +UPB_INLINE uint32_t _upb_BigEndian_Swap32(uint32_t val) { + if (_upb_IsLittleEndian()) return val; + + return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | + ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24); +} + +UPB_INLINE uint64_t _upb_BigEndian_Swap64(uint64_t val) { + if (_upb_IsLittleEndian()) return val; + + return ((uint64_t)_upb_BigEndian_Swap32((uint32_t)val) << 32) | + _upb_BigEndian_Swap32((uint32_t)(val >> 32)); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_WIRE_INTERNAL_SWAP_H_ */ + +#ifndef UPB_WIRE_READER_H_ +#define UPB_WIRE_READER_H_ + + +#ifndef UPB_WIRE_TYPES_H_ +#define UPB_WIRE_TYPES_H_ + +// A list of types as they are encoded on the wire. +typedef enum { + kUpb_WireType_Varint = 0, + kUpb_WireType_64Bit = 1, + kUpb_WireType_Delimited = 2, + kUpb_WireType_StartGroup = 3, + kUpb_WireType_EndGroup = 4, + kUpb_WireType_32Bit = 5 +} upb_WireType; + +#endif /* UPB_WIRE_TYPES_H_ */ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// The upb_WireReader interface is suitable for general-purpose parsing of +// protobuf binary wire format. It is designed to be used along with +// upb_EpsCopyInputStream for buffering, and all parsing routines in this file +// assume that at least kUpb_EpsCopyInputStream_SlopBytes worth of data is +// available to read without any bounds checks. + +#define kUpb_WireReader_WireTypeMask 7 +#define kUpb_WireReader_WireTypeBits 3 + +typedef struct { + const char* ptr; + uint64_t val; +} _upb_WireReader_ReadLongVarintRet; + +_upb_WireReader_ReadLongVarintRet _upb_WireReader_ReadLongVarint( + const char* ptr, uint64_t val); + +static UPB_FORCEINLINE const char* _upb_WireReader_ReadVarint(const char* ptr, + uint64_t* val, + int maxlen, + uint64_t maxval) { + uint64_t byte = (uint8_t)*ptr; + if (UPB_LIKELY((byte & 0x80) == 0)) { + *val = (uint32_t)byte; + return ptr + 1; + } + const char* start = ptr; + _upb_WireReader_ReadLongVarintRet res = + _upb_WireReader_ReadLongVarint(ptr, byte); + if (!res.ptr || (maxlen < 10 && res.ptr - start > maxlen) || + res.val > maxval) { + return NULL; // Malformed. + } + *val = res.val; + return res.ptr; +} + +// Parses a tag into `tag`, and returns a pointer past the end of the tag, or +// NULL if there was an error in the tag data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +static UPB_FORCEINLINE const char* upb_WireReader_ReadTag(const char* ptr, + uint32_t* tag) { + uint64_t val; + ptr = _upb_WireReader_ReadVarint(ptr, &val, 5, UINT32_MAX); + if (!ptr) return NULL; + *tag = val; + return ptr; +} + +// Given a tag, returns the field number. +UPB_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag) { + return tag >> kUpb_WireReader_WireTypeBits; +} + +// Given a tag, returns the wire type. +UPB_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag) { + return tag & kUpb_WireReader_WireTypeMask; +} + +UPB_INLINE const char* upb_WireReader_ReadVarint(const char* ptr, + uint64_t* val) { + return _upb_WireReader_ReadVarint(ptr, val, 10, UINT64_MAX); +} + +// Skips data for a varint, returning a pointer past the end of the varint, or +// NULL if there was an error in the varint data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_SkipVarint(const char* ptr) { + uint64_t val; + return upb_WireReader_ReadVarint(ptr, &val); +} + +// Reads a varint indicating the size of a delimited field into `size`, or +// NULL if there was an error in the varint data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadSize(const char* ptr, int* size) { + uint64_t size64; + ptr = upb_WireReader_ReadVarint(ptr, &size64); + if (!ptr || size64 >= INT32_MAX) return NULL; + *size = size64; + return ptr; +} + +// Reads a fixed32 field, performing byte swapping if necessary. +// +// REQUIRES: there must be at least 4 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadFixed32(const char* ptr, void* val) { + uint32_t uval; + memcpy(&uval, ptr, 4); + uval = _upb_BigEndian_Swap32(uval); + memcpy(val, &uval, 4); + return ptr + 4; +} + +// Reads a fixed64 field, performing byte swapping if necessary. +// +// REQUIRES: there must be at least 4 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadFixed64(const char* ptr, void* val) { + uint64_t uval; + memcpy(&uval, ptr, 8); + uval = _upb_BigEndian_Swap64(uval); + memcpy(val, &uval, 8); + return ptr + 8; +} + +const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag, + int depth_limit, + upb_EpsCopyInputStream* stream); + +// Skips data for a group, returning a pointer past the end of the group, or +// NULL if there was an error parsing the group. The `tag` argument should be +// the start group tag that begins the group. The `depth_limit` argument +// indicates how many levels of recursion the group is allowed to have before +// reporting a parse error (this limit exists to protect against stack +// overflow). +// +// TODO: evaluate how the depth_limit should be specified. Do users need +// control over this? +UPB_INLINE const char* upb_WireReader_SkipGroup( + const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { + return _upb_WireReader_SkipGroup(ptr, tag, 100, stream); +} + +UPB_INLINE const char* _upb_WireReader_SkipValue( + const char* ptr, uint32_t tag, int depth_limit, + upb_EpsCopyInputStream* stream) { + switch (upb_WireReader_GetWireType(tag)) { + case kUpb_WireType_Varint: + return upb_WireReader_SkipVarint(ptr); + case kUpb_WireType_32Bit: + return ptr + 4; + case kUpb_WireType_64Bit: + return ptr + 8; + case kUpb_WireType_Delimited: { + int size; + ptr = upb_WireReader_ReadSize(ptr, &size); + if (!ptr) return NULL; + ptr += size; + return ptr; + } + case kUpb_WireType_StartGroup: + return _upb_WireReader_SkipGroup(ptr, tag, depth_limit, stream); + case kUpb_WireType_EndGroup: + return NULL; // Should be handled before now. + default: + return NULL; // Unknown wire type. + } +} + +// Skips data for a wire value of any type, returning a pointer past the end of +// the data, or NULL if there was an error parsing the group. The `tag` argument +// should be the tag that was just parsed. The `depth_limit` argument indicates +// how many levels of recursion a group is allowed to have before reporting a +// parse error (this limit exists to protect against stack overflow). +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +// +// TODO: evaluate how the depth_limit should be specified. Do users need +// control over this? +UPB_INLINE const char* upb_WireReader_SkipValue( + const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { + return _upb_WireReader_SkipValue(ptr, tag, 100, stream); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_WIRE_READER_H_ + // This should #undef all macros #defined in def.inc #undef UPB_SIZE @@ -13220,7 +13885,9 @@ UPB_INLINE uint32_t _upb_FastDecoder_LoadTag(const char* ptr) { #undef UPB_GNUC_MIN #undef UPB_DESCRIPTOR_UPB_H_FILENAME #undef UPB_DESC +#undef UPB_DESC_MINITABLE #undef UPB_IS_GOOGLE3 #undef UPB_ATOMIC #undef UPB_USE_C11_ATOMICS #undef UPB_PRIVATE +#undef UPB_ONLYBITS diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index d24a5328e9..4fab47f357 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -32,7 +32,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_setter, 0, 0, 1) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() -#define PHP_PROTOBUF_VERSION "3.24.0" +#define PHP_PROTOBUF_VERSION "3.25.0" // ptr -> PHP object cache. This is a weak map that caches lazily-created // wrapper objects around upb types: diff --git a/pkg/BUILD.bazel b/pkg/BUILD.bazel index 340fbaf453..55079a67e2 100644 --- a/pkg/BUILD.bazel +++ b/pkg/BUILD.bazel @@ -220,6 +220,7 @@ cc_dist_library( "//src/google/protobuf:lite_test_util", "//src/google/protobuf:test_util", "//src/google/protobuf:test_util2", + "//src/google/protobuf:unredacted_debug_format_for_test", "//src/google/protobuf/compiler:annotation_test_util", "//src/google/protobuf/compiler/cpp:unittest_lib", "//src/google/protobuf/io:test_zero_copy_stream", diff --git a/pkg/cc_dist_library.bzl b/pkg/cc_dist_library.bzl index 9fc2c414e6..5252c9bedf 100644 --- a/pkg/cc_dist_library.bzl +++ b/pkg/cc_dist_library.bzl @@ -137,9 +137,11 @@ def _flatten_target_files(targets): return depset(transitive = [ target.files for target in targets - # Filter out targets from external workspaces - if target.label.workspace_name == "" or - target.label.workspace_name == "com_google_protobuf" + # Filter out targets from external workspaces. We also filter out + # utf8_range since that has a separate CMake build for now. + if (target.label.workspace_name == "" or + target.label.workspace_name == "com_google_protobuf") and + not target.label.package.startswith("third_party/utf8_range") ]) def _get_transitive_sources(targets, attr, deps): diff --git a/protobuf.bzl b/protobuf.bzl index d96eeb4c9a..3c8afcc17f 100644 --- a/protobuf.bzl +++ b/protobuf.bzl @@ -2,7 +2,6 @@ load("@bazel_skylib//lib:versions.bzl", "versions") load("@rules_cc//cc:defs.bzl", "objc_library") load("@rules_proto//proto:defs.bzl", "ProtoInfo") load("@rules_python//python:defs.bzl", "py_library") -load("@rules_ruby//ruby:defs.bzl", "ruby_library") def _GetPath(ctx, path): if ctx.label.workspace_root: @@ -81,6 +80,7 @@ def _proto_gen_impl(ctx): srcs = ctx.files.srcs langs = ctx.attr.langs or [] out_type = ctx.attr.out_type + enable_editions = ctx.attr.enable_editions deps = depset(direct = ctx.files.srcs) source_dir = _SourceDir(ctx) gen_dir = _GenDir(ctx).rstrip("/") @@ -131,6 +131,8 @@ def _proto_gen_impl(ctx): generated_files = [] for src in srcs: args = [] + if enable_editions: + args.append("--experimental_editions") in_gen_dir = src.root.path == gen_dir if in_gen_dir: @@ -248,6 +250,7 @@ _proto_gen = rule( attrs = { "srcs": attr.label_list(allow_files = True), "deps": attr.label_list(providers = [ProtoGenInfo]), + "enable_editions": attr.bool(), "includes": attr.string_list(), "protoc": attr.label( cfg = "exec", @@ -407,11 +410,11 @@ def internal_objc_proto_library( includes = ["."], default_runtime = Label("//:protobuf_objc"), protoc = Label("//:protoc"), + enable_editions = False, testonly = None, visibility = ["//visibility:public"], **kwargs): - """Bazel rule to create a Objective-C protobuf library from proto source - files + """Bazel rule to create a Objective-C protobuf library from proto sources NOTE: the rule is only an internal workaround to generate protos. The interface may change and the rule may be removed when bazel has introduced @@ -424,9 +427,10 @@ def internal_objc_proto_library( outs: a list of expected output files. proto_deps: a list of proto file dependencies that don't have a objc_proto_library rule. - include: a string indicating the include path of the .proto files. + includes: a string indicating the include path of the .proto files. default_runtime: the Objective-C Protobuf runtime protoc: the label of the protocol compiler to generate the sources. + enable_editions: if editions should be enabled while invoking the compiler. testonly: common rule attribute (see: https://bazel.build/reference/be/common-definitions#common-attributes) visibility: the visibility of the generated files. @@ -441,6 +445,7 @@ def internal_objc_proto_library( testonly = testonly, srcs = proto_deps, protoc = protoc, + enable_editions = enable_editions, includes = includes, ) full_deps.append(":%s_deps_genproto" % name) @@ -455,6 +460,7 @@ def internal_objc_proto_library( out_type = "hdrs", includes = includes, protoc = protoc, + enable_editions = enable_editions, testonly = testonly, visibility = visibility, tags = ["manual"], @@ -468,6 +474,7 @@ def internal_objc_proto_library( out_type = "srcs", includes = includes, protoc = protoc, + enable_editions = enable_editions, testonly = testonly, visibility = visibility, tags = ["manual"], @@ -490,6 +497,7 @@ def internal_objc_proto_library( def internal_ruby_proto_library( name, + ruby_library, srcs = [], deps = [], includes = ["."], @@ -506,6 +514,7 @@ def internal_ruby_proto_library( Args: name: the name of the ruby_proto_library. + ruby_library: the ruby library rules to use. srcs: the .proto files to compile. deps: a list of dependency labels; must be a internal_ruby_proto_library. includes: a string indicating the include path of the .proto files. diff --git a/protobuf_deps.bzl b/protobuf_deps.bzl index d055eed8c6..9be6815582 100644 --- a/protobuf_deps.bzl +++ b/protobuf_deps.bzl @@ -68,20 +68,12 @@ def protobuf_deps(): build_file = Label("//:third_party/jsoncpp.BUILD"), ) - if not native.existing_rule("utf8_range"): - _github_archive( - name = "utf8_range", - repo = "https://github.com/protocolbuffers/utf8_range", - commit = "d863bc33e15cba6d873c878dcca9e6fe52b2f8cb", - sha256 = "568988b5f7261ca181468dba38849fabf59dd9200fb2ed4b2823da187ef84d8c", - ) - if not native.existing_rule("rules_cc"): _github_archive( name = "rules_cc", repo = "https://github.com/bazelbuild/rules_cc", - commit = "818289e5613731ae410efb54218a4077fb9dbb03", - sha256 = "0adbd6f567291ad526e82c765e15aed33cea5e256eeba129f1501142c2c56610", + commit = "c8c38f8c710cbbf834283e4777916b68261b359c", # 0.0.9 + sha256 = "5f862a44bbd032e1b48ed53c9c211ba2a1da60e10c5baa01c97369c249299ecb", ) if not native.existing_rule("rules_java"): @@ -102,19 +94,11 @@ def protobuf_deps(): ) if not native.existing_rule("rules_python"): - _github_archive( + http_archive( name = "rules_python", - repo = "https://github.com/bazelbuild/rules_python", - commit = "02b521fce3c7b36b05813aa986d72777cc3ee328", # 0.24.0 - sha256 = "f9e4f6acf82449324d56669bda4bdb28b48688ad2990d8b39fa5b93ed39c9ad1", - ) - - if not native.existing_rule("rules_ruby"): - _github_archive( - name = "rules_ruby", - repo = "https://github.com/protocolbuffers/rules_ruby", - commit = "b7f3e9756f3c45527be27bc38840d5a1ba690436", - sha256 = "347927fd8de6132099fcdc58e8f7eab7bde4eb2fd424546b9cd4f1c6f8f8bad8", + sha256 = "9d04041ac92a0985e344235f5d946f71ac543f1b1565f2cdbc9a2aaee8adf55b", + strip_prefix = "rules_python-0.26.0", + url = "https://github.com/bazelbuild/rules_python/releases/download/0.26.0/rules_python-0.26.0.tar.gz", ) if not native.existing_rule("rules_jvm_external"): @@ -138,8 +122,8 @@ def protobuf_deps(): if not native.existing_rule("build_bazel_rules_apple"): http_archive( name = "build_bazel_rules_apple", - sha256 = "f94e6dddf74739ef5cb30f000e13a2a613f6ebfa5e63588305a71fce8a8a9911", - url = "https://github.com/bazelbuild/rules_apple/releases/download/1.1.3/rules_apple.1.1.3.tar.gz", + sha256 = "34c41bfb59cdaea29ac2df5a2fa79e5add609c71bb303b2ebb10985f93fa20e7", + url = "https://github.com/bazelbuild/rules_apple/releases/download/3.1.1/rules_apple.3.1.1.tar.gz", ) if not native.existing_rule("io_bazel_rules_kotlin"): diff --git a/protobuf_version.bzl b/protobuf_version.bzl index e428407720..a122dc377f 100644 --- a/protobuf_version.bzl +++ b/protobuf_version.bzl @@ -1,6 +1,6 @@ """ Contains version numbers to be used in other bzl files """ -PROTOC_VERSION = "24.0" -PROTOBUF_JAVA_VERSION = "3.24.0" -PROTOBUF_PYTHON_VERSION = "4.24.0" -PROTOBUF_PHP_VERSION = "3.24.0" -PROTOBUF_RUBY_VERSION = "3.24.0" +PROTOC_VERSION = "25.0" +PROTOBUF_JAVA_VERSION = "3.25.0" +PROTOBUF_PYTHON_VERSION = "4.25.0" +PROTOBUF_PHP_VERSION = "3.25.0" +PROTOBUF_RUBY_VERSION = "3.25.0" diff --git a/protos/BUILD b/protos/BUILD index d037b60ac9..867ce331ee 100644 --- a/protos/BUILD +++ b/protos/BUILD @@ -36,7 +36,6 @@ cc_library( "//upb:message", "//upb:message_copy", "//upb:message_types", - "//upb:port", "@com_google_absl//absl/base:core_headers", "@com_google_absl//absl/strings", ], diff --git a/protos/protos.cc b/protos/protos.cc index 29b9fbe254..888bbb4bbd 100644 --- a/protos/protos.cc +++ b/protos/protos.cc @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "protos/protos.h" @@ -138,8 +115,8 @@ bool HasExtensionOrUnknown(const upb_Message* msg, const upb_MiniTableExtension* eid) { MessageLock msg_lock(msg); return _upb_Message_Getext(msg, eid) != nullptr || - upb_MiniTable_FindUnknown(msg, eid->field.number, 0).status == - kUpb_FindUnknown_Ok; + upb_Message_FindUnknown(msg, upb_MiniTableExtension_Number(eid), 0) + .status == kUpb_FindUnknown_Ok; } const upb_Message_Extension* GetOrPromoteExtension( @@ -193,8 +170,9 @@ absl::Status MoveExtension(upb_Message* message, upb_Arena* message_arena, if (message_arena != extension_arena) { // Try fuse, if fusing is not allowed or fails, create copy of extension. if (!upb_Arena_Fuse(message_arena, extension_arena)) { - msg_ext->data.ptr = - DeepClone(extension, msg_ext->ext->sub.submsg, message_arena); + msg_ext->data.ptr = DeepClone( + extension, upb_MiniTableExtension_GetSubMessage(msg_ext->ext), + message_arena); return absl::OkStatus(); } } @@ -212,7 +190,8 @@ absl::Status SetExtension(upb_Message* message, upb_Arena* message_arena, } // Clone extension into target message arena. msg_ext->data.ptr = - DeepClone(extension, msg_ext->ext->sub.submsg, message_arena); + DeepClone(extension, upb_MiniTableExtension_GetSubMessage(msg_ext->ext), + message_arena); return absl::OkStatus(); } diff --git a/protos/protos.h b/protos/protos.h index 195d793540..27d8c4eb43 100644 --- a/protos/protos.h +++ b/protos/protos.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef UPB_PROTOS_PROTOS_H_ #define UPB_PROTOS_PROTOS_H_ @@ -41,6 +18,7 @@ #include "upb/message/copy.h" #include "upb/message/internal/accessors.h" #include "upb/message/internal/extension.h" +#include "upb/mini_table/extension.h" #include "upb/wire/decode.h" #include "upb/wire/encode.h" @@ -435,7 +413,8 @@ absl::StatusOr> GetExtension( const_cast(internal::GetInternalMsg(message)), id.mini_table_ext(), ::protos::internal::GetArena(message)); if (!ext) { - return ExtensionNotFoundError(id.mini_table_ext()->field.number); + return ExtensionNotFoundError( + upb_MiniTableExtension_Number(id.mini_table_ext())); } return Ptr(::protos::internal::CreateMessage( ext->data.ptr, ::protos::internal::GetArena(message))); diff --git a/protos/protos_extension_lock.cc b/protos/protos_extension_lock.cc index dbb2fc2ed2..ba533429c6 100644 --- a/protos/protos_extension_lock.cc +++ b/protos/protos_extension_lock.cc @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "protos/protos_extension_lock.h" diff --git a/protos/protos_extension_lock.h b/protos/protos_extension_lock.h index 36d66f12d6..6abe9b4bad 100644 --- a/protos/protos_extension_lock.h +++ b/protos/protos_extension_lock.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef UPB_PROTOS_PROTOS_EXTENSION_LOCK_H_ #define UPB_PROTOS_PROTOS_EXTENSION_LOCK_H_ diff --git a/protos/protos_extension_lock_test.cc b/protos/protos_extension_lock_test.cc index a0ce399cc1..9c2444b606 100644 --- a/protos/protos_extension_lock_test.cc +++ b/protos/protos_extension_lock_test.cc @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "protos/protos_extension_lock.h" diff --git a/protos/protos_internal.h b/protos/protos_internal.h index 0a1f194d3a..e9733680a4 100644 --- a/protos/protos_internal.h +++ b/protos/protos_internal.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef UPB_PROTOS_PROTOS_INTERNAL_H_ #define UPB_PROTOS_PROTOS_INTERNAL_H_ diff --git a/protos/protos_internal_test.cc b/protos/protos_internal_test.cc index a173665acc..26849eea09 100644 --- a/protos/protos_internal_test.cc +++ b/protos/protos_internal_test.cc @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "protos/protos_internal.h" diff --git a/protos/protos_traits.h b/protos/protos_traits.h index 92b9dc33b6..7b4fe2edfc 100644 --- a/protos/protos_traits.h +++ b/protos/protos_traits.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef THIRD_PARTY_UPB_PROTOS_PROTOS_TRAITS_H_ #define THIRD_PARTY_UPB_PROTOS_PROTOS_TRAITS_H_ diff --git a/protos/repeated_field.h b/protos/repeated_field.h index da42c44bc1..6d37b569fa 100644 --- a/protos/repeated_field.h +++ b/protos/repeated_field.h @@ -1,36 +1,15 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef UPB_PROTOS_REPEATED_FIELD_H_ #define UPB_PROTOS_REPEATED_FIELD_H_ +#include + #include #include #include @@ -45,11 +24,7 @@ #include "upb/message/copy.h" #include "upb/message/types.h" -// Must be last: -#include "upb/port/def.inc" - namespace protos { - namespace internal { // Shared implementation of repeated fields for absl::string_view and @@ -208,9 +183,9 @@ class RepeatedFieldStringProxy void push_back(T t) { upb_MessageValue message_value; // Copy string to arena. - UPB_ASSERT(this->arena_); + assert(this->arena_); char* data = (char*)upb_Arena_Malloc(this->arena_, t.size()); - UPB_ASSERT(data); + assert(data); memcpy(data, t.data(), t.size()); message_value.str_val = upb_StringView_FromDataAndSize(data, t.size()); upb_Array_Append(this->arr_, message_value, this->arena_); @@ -320,6 +295,4 @@ class RepeatedField { } // namespace protos -#include "upb/port/undef.inc" - #endif // UPB_PROTOS_REPEATED_FIELD_H_ diff --git a/protos/repeated_field_iterator.h b/protos/repeated_field_iterator.h index 6ae25de14c..79c284c8db 100644 --- a/protos/repeated_field_iterator.h +++ b/protos/repeated_field_iterator.h @@ -1,32 +1,10 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + #ifndef UPB_PROTOS_REPEATED_FIELD_ITERATOR_H_ #define UPB_PROTOS_REPEATED_FIELD_ITERATOR_H_ @@ -40,11 +18,7 @@ #include "upb/base/string_view.h" #include "upb/mem/arena.h" #include "upb/message/array.h" -#include "upb/message/copy.h" - -// Must be last: #include "upb/message/types.h" -#include "upb/port/def.inc" namespace protos { namespace internal { diff --git a/protos/repeated_field_iterator_test.cc b/protos/repeated_field_iterator_test.cc index a8de90017c..593ee07395 100644 --- a/protos/repeated_field_iterator_test.cc +++ b/protos/repeated_field_iterator_test.cc @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "protos/repeated_field_iterator.h" diff --git a/protos_generator/gen_accessors.cc b/protos_generator/gen_accessors.cc index b9101950c3..5a121c82bd 100644 --- a/protos_generator/gen_accessors.cc +++ b/protos_generator/gen_accessors.cc @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "protos_generator/gen_accessors.h" diff --git a/protos_generator/gen_accessors.h b/protos_generator/gen_accessors.h index 8372fc3486..0b5910e870 100644 --- a/protos_generator/gen_accessors.h +++ b/protos_generator/gen_accessors.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef UPB_PROTOS_GENERATOR_ACCESSORS_H_ #define UPB_PROTOS_GENERATOR_ACCESSORS_H_ diff --git a/protos_generator/gen_enums.cc b/protos_generator/gen_enums.cc index 7c535a7e3d..6366caaebf 100644 --- a/protos_generator/gen_enums.cc +++ b/protos_generator/gen_enums.cc @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "protos_generator/gen_enums.h" diff --git a/protos_generator/gen_enums.h b/protos_generator/gen_enums.h index 607876225a..e07c559584 100644 --- a/protos_generator/gen_enums.h +++ b/protos_generator/gen_enums.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef UPB_PROTOS_GENERATOR_ENUMS_H_ #define UPB_PROTOS_GENERATOR_ENUMS_H_ diff --git a/protos_generator/gen_extensions.cc b/protos_generator/gen_extensions.cc index be0cbc5210..f65c1cca22 100644 --- a/protos_generator/gen_extensions.cc +++ b/protos_generator/gen_extensions.cc @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "protos_generator/gen_extensions.h" diff --git a/protos_generator/gen_extensions.h b/protos_generator/gen_extensions.h index 8ec740aadb..71c91c84c7 100644 --- a/protos_generator/gen_extensions.h +++ b/protos_generator/gen_extensions.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef UPB_PROTOS_GENERATOR_GEN_EXTENSIONS_H_ #define UPB_PROTOS_GENERATOR_GEN_EXTENSIONS_H_ diff --git a/protos_generator/gen_messages.cc b/protos_generator/gen_messages.cc index 251920abc6..89ca8611e6 100644 --- a/protos_generator/gen_messages.cc +++ b/protos_generator/gen_messages.cc @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "protos_generator/gen_messages.h" diff --git a/protos_generator/gen_messages.h b/protos_generator/gen_messages.h index 323696449e..4ba2054564 100644 --- a/protos_generator/gen_messages.h +++ b/protos_generator/gen_messages.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef UPB_PROTOS_GENERATOR_GEN_MESSAGES_H_ #define UPB_PROTOS_GENERATOR_GEN_MESSAGES_H_ diff --git a/protos_generator/gen_repeated_fields.cc b/protos_generator/gen_repeated_fields.cc index 57b13f2745..12d243ae83 100644 --- a/protos_generator/gen_repeated_fields.cc +++ b/protos_generator/gen_repeated_fields.cc @@ -1,32 +1,10 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + #include "protos_generator/gen_repeated_fields.h" #include diff --git a/protos_generator/gen_repeated_fields.h b/protos_generator/gen_repeated_fields.h index 1650eb0c06..d8f83b76a1 100644 --- a/protos_generator/gen_repeated_fields.h +++ b/protos_generator/gen_repeated_fields.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef THIRD_PARTY_UPB_PROTOS_GENERATOR_GEN_REPEATED_FIELDS_H_ #define THIRD_PARTY_UPB_PROTOS_GENERATOR_GEN_REPEATED_FIELDS_H_ diff --git a/protos_generator/gen_utils.cc b/protos_generator/gen_utils.cc index 79dd5a188d..eb524bdf45 100644 --- a/protos_generator/gen_utils.cc +++ b/protos_generator/gen_utils.cc @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "protos_generator/gen_utils.h" diff --git a/protos_generator/gen_utils.h b/protos_generator/gen_utils.h index 71f325f585..6cd5f7d3a0 100644 --- a/protos_generator/gen_utils.h +++ b/protos_generator/gen_utils.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef UPB_PROTOS_GENERATOR_GEN_UTILS_H_ #define UPB_PROTOS_GENERATOR_GEN_UTILS_H_ diff --git a/protos_generator/names.cc b/protos_generator/names.cc index e31edbc747..13c8e01ca4 100644 --- a/protos_generator/names.cc +++ b/protos_generator/names.cc @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "protos_generator/names.h" diff --git a/protos_generator/names.h b/protos_generator/names.h index efa01ce067..3509be9422 100644 --- a/protos_generator/names.h +++ b/protos_generator/names.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef UPB_PROTOS_GENERATOR_NAMES_H_ #define UPB_PROTOS_GENERATOR_NAMES_H_ diff --git a/protos_generator/output.cc b/protos_generator/output.cc index 72cd4e56d8..8057450ee9 100644 --- a/protos_generator/output.cc +++ b/protos_generator/output.cc @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "protos_generator/output.h" diff --git a/protos_generator/output.h b/protos_generator/output.h index 0db6ad5fa5..828a4239c4 100644 --- a/protos_generator/output.h +++ b/protos_generator/output.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef UPB_PROTOS_GENERATOR_OUTPUT_H #define UPB_PROTOS_GENERATOR_OUTPUT_H diff --git a/protos_generator/protoc-gen-upb-protos.cc b/protos_generator/protoc-gen-upb-protos.cc index 53224b5dba..4bb409a0ba 100644 --- a/protos_generator/protoc-gen-upb-protos.cc +++ b/protos_generator/protoc-gen-upb-protos.cc @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include diff --git a/protos_generator/tests/BUILD b/protos_generator/tests/BUILD index e4b236626f..c47a71fec4 100644 --- a/protos_generator/tests/BUILD +++ b/protos_generator/tests/BUILD @@ -1,5 +1,5 @@ -# Copyright (c) 2009-2021, Google LLC -# All rights reserved. +# Protocol Buffers - Google's data interchange format +# Copyright 2023 Google LLC. All rights reserved. # # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file or at diff --git a/protos_generator/tests/child_model.proto b/protos_generator/tests/child_model.proto index c7af6f13e3..b3779f32ab 100644 --- a/protos_generator/tests/child_model.proto +++ b/protos_generator/tests/child_model.proto @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd syntax = "proto3"; diff --git a/protos_generator/tests/legacy-name.proto b/protos_generator/tests/legacy-name.proto index 0f256adb1a..f6ac9a2361 100644 --- a/protos_generator/tests/legacy-name.proto +++ b/protos_generator/tests/legacy-name.proto @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd syntax = "proto3"; diff --git a/protos_generator/tests/naming_conflict.proto b/protos_generator/tests/naming_conflict.proto index 414f7c636c..3f08c0f81d 100644 --- a/protos_generator/tests/naming_conflict.proto +++ b/protos_generator/tests/naming_conflict.proto @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd syntax = "proto3"; diff --git a/protos_generator/tests/no_package.proto b/protos_generator/tests/no_package.proto index 37d6df83b5..ebd9c2fda6 100644 --- a/protos_generator/tests/no_package.proto +++ b/protos_generator/tests/no_package.proto @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd syntax = "proto2"; diff --git a/protos_generator/tests/no_package_enum_user.proto b/protos_generator/tests/no_package_enum_user.proto index ebf8c67ad8..ec19e54428 100644 --- a/protos_generator/tests/no_package_enum_user.proto +++ b/protos_generator/tests/no_package_enum_user.proto @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd syntax = "proto2"; diff --git a/protos_generator/tests/test_enum.proto b/protos_generator/tests/test_enum.proto index ed41c3ce41..2d12340312 100644 --- a/protos_generator/tests/test_enum.proto +++ b/protos_generator/tests/test_enum.proto @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd syntax = "proto3"; diff --git a/protos_generator/tests/test_extension.proto b/protos_generator/tests/test_extension.proto index 3a1a3c67b9..d776cd40f4 100644 --- a/protos_generator/tests/test_extension.proto +++ b/protos_generator/tests/test_extension.proto @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd syntax = "proto2"; diff --git a/protos_generator/tests/test_generated.cc b/protos_generator/tests/test_generated.cc index 121251b6a7..14638af06d 100644 --- a/protos_generator/tests/test_generated.cc +++ b/protos_generator/tests/test_generated.cc @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include #include diff --git a/protos_generator/tests/test_model.proto b/protos_generator/tests/test_model.proto index e133624215..a84c37a983 100644 --- a/protos_generator/tests/test_model.proto +++ b/protos_generator/tests/test_model.proto @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd syntax = "proto2"; diff --git a/python/BUILD b/python/BUILD.bazel similarity index 99% rename from python/BUILD rename to python/BUILD.bazel index 92e9c496c5..f604badcf6 100644 --- a/python/BUILD +++ b/python/BUILD.bazel @@ -203,5 +203,6 @@ py_extension( "//upb/util:compare", "//upb/util:def_to_proto", "//upb/util:required_fields", + "//third_party/utf8_range", ], ) diff --git a/python/build_targets.bzl b/python/build_targets.bzl index 91c8dfb37e..05ed1637ce 100644 --- a/python/build_targets.bzl +++ b/python/build_targets.bzl @@ -12,6 +12,7 @@ load("//:protobuf.bzl", "internal_py_proto_library") load("//build_defs:arch_tests.bzl", "aarch64_test", "x86_64_test") load("//build_defs:cpp_opts.bzl", "COPTS") load("//conformance:defs.bzl", "conformance_test") +load("//src/google/protobuf/editions:defaults.bzl", "compile_edition_defaults", "embed_edition_defaults") load(":internal.bzl", "internal_copy_files", "internal_py_test") def build_targets(name): @@ -120,7 +121,6 @@ def build_targets(name): deps = [ ":proto_api", "//:protobuf", - "//src/google/protobuf:descriptor_legacy", ] + select({ "//conditions:default": [], ":use_fast_cpp_protos": ["//external:python_headers"], @@ -143,8 +143,23 @@ def build_targets(name): ], ) - py_library( - name = "python_srcs", + compile_edition_defaults( + name = "python_edition_defaults", + srcs = ["//:descriptor_proto"], + maximum_edition = "2023", + minimum_edition = "PROTO2", + ) + + embed_edition_defaults( + name = "embedded_python_edition_defaults_generate", + defaults = "python_edition_defaults", + output = "google/protobuf/internal/python_edition_defaults.py", + placeholder = "DEFAULTS_VALUE", + template = "google/protobuf/internal/python_edition_defaults.py.template", + ) + + native.filegroup( + name = "python_src_files", srcs = native.glob( [ "google/protobuf/**/*.py", @@ -154,7 +169,12 @@ def build_targets(name): "google/protobuf/internal/test_util.py", "google/protobuf/internal/import_test_package/__init__.py", ], - ), + ) + ["google/protobuf/internal/python_edition_defaults.py"], + ) + + py_library( + name = "python_srcs", + srcs = [":python_src_files"], imports = ["python"], srcs_version = "PY2AND3", visibility = [ @@ -196,19 +216,13 @@ def build_targets(name): ) internal_copy_files( - name = "copied_test_messages_proto2_files", + name = "copied_conformance_test_files", testonly = 1, srcs = [ "//src/google/protobuf:test_messages_proto2.proto", - ], - strip_prefix = "src", - ) - - internal_copy_files( - name = "copied_test_messages_proto3_files", - testonly = 1, - srcs = [ "//src/google/protobuf:test_messages_proto3.proto", + "//src/google/protobuf/editions:golden/test_messages_proto2_editions.proto", + "//src/google/protobuf/editions:golden/test_messages_proto3_editions.proto", ], strip_prefix = "src", ) @@ -241,22 +255,9 @@ def build_targets(name): ) internal_py_proto_library( - name = "test_messages_proto2_py_proto", + name = "conformance_test_py_proto", testonly = 1, - srcs = [":copied_test_messages_proto2_files"], - include = ".", - default_runtime = "//:protobuf_python", - protoc = "//:protoc", - visibility = [ - "//conformance:__pkg__", - "//python:__subpackages__", - ], - ) - - internal_py_proto_library( - name = "test_messages_proto3_py_proto", - testonly = 1, - srcs = [":copied_test_messages_proto3_files"], + srcs = [":copied_conformance_test_files"], include = ".", default_runtime = "//:protobuf_python", protoc = "//:protoc", @@ -404,6 +405,7 @@ def build_targets(name): ":use_fast_cpp_protos": ["@platforms//:incompatible"], "//conditions:default": [], }), + maximum_edition = "2023", testee = "//conformance:conformance_python", text_format_failure_list = "//conformance:text_format_failure_list_python.txt", ) @@ -418,30 +420,36 @@ def build_targets(name): ":use_fast_cpp_protos": [], "//conditions:default": ["@platforms//:incompatible"], }), + maximum_edition = "2023", testee = "//conformance:conformance_python", text_format_failure_list = "//conformance:text_format_failure_list_python_cpp.txt", ) + conformance_test( + name = "conformance_test_upb", + env = {"PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION": "upb"}, + failure_list = "//conformance:failure_list_python_upb.txt", + target_compatible_with = select({ + "@system_python//:none": ["@platforms//:incompatible"], + ":use_fast_cpp_protos": ["@platforms//:incompatible"], + "//conditions:default": [], + }), + maximum_edition = "2023", + testee = "//conformance:conformance_python", + text_format_failure_list = "//conformance:text_format_failure_list_python_upb.txt", + ) + ################################################################################ # Distribution files ################################################################################ pkg_files( name = "python_source_files", - srcs = native.glob( - [ - "google/protobuf/**/*.py", - ], - exclude = [ - "google/protobuf/internal/*_test.py", - "google/protobuf/internal/test_util.py", - "google/protobuf/internal/import_test_package/__init__.py", - ], - ) + [ + srcs = [ + ":python_src_files", "README.md", "google/__init__.py", "setup.cfg", - "tox.ini", ], strip_prefix = "", visibility = ["//python/dist:__pkg__"], @@ -456,7 +464,7 @@ def build_targets(name): "google/protobuf/pyext/*.cc", "google/protobuf/pyext/*.h", ]) + [ - "BUILD", + "BUILD.bazel", "MANIFEST.in", "README.md", "build_targets.bzl", @@ -467,7 +475,6 @@ def build_targets(name): "python_version_test.py", "setup.cfg", "setup.py", - "tox.ini", ], strip_prefix = strip_prefix.from_root(""), visibility = ["//pkg:__pkg__"], diff --git a/python/convert.c b/python/convert.c index 413c42f735..2105c98a63 100644 --- a/python/convert.c +++ b/python/convert.c @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "python/convert.h" @@ -35,6 +12,7 @@ #include "upb/message/map.h" #include "upb/reflection/message.h" #include "upb/util/compare.h" +#include "utf8_range.h" // Must be last. #include "upb/port/def.inc" @@ -259,20 +237,27 @@ bool PyUpb_PyToUpb(PyObject* obj, const upb_FieldDef* f, upb_MessageValue* val, } case kUpb_CType_String: { Py_ssize_t size; - const char* ptr; - PyObject* unicode = NULL; if (PyBytes_Check(obj)) { - unicode = obj = PyUnicode_FromEncodedObject(obj, "utf-8", NULL); - if (!obj) return false; - } - ptr = PyUnicode_AsUTF8AndSize(obj, &size); - if (PyErr_Occurred()) { - Py_XDECREF(unicode); - return false; + // Use the object's bytes if they are valid UTF-8. + char* ptr; + if (PyBytes_AsStringAndSize(obj, &ptr, &size) < 0) return false; + if (utf8_range2((const unsigned char*)ptr, size) != 0) { + // Invalid UTF-8. Try to convert the message to a Python Unicode + // object, even though we know this will fail, just to get the + // idiomatic Python error message. + obj = PyUnicode_FromEncodedObject(obj, "utf-8", NULL); + assert(!obj); + return false; + } + *val = PyUpb_MaybeCopyString(ptr, size, arena); + return true; + } else { + const char* ptr; + ptr = PyUnicode_AsUTF8AndSize(obj, &size); + if (PyErr_Occurred()) return false; + *val = PyUpb_MaybeCopyString(ptr, size, arena); + return true; } - *val = PyUpb_MaybeCopyString(ptr, size, arena); - Py_XDECREF(unicode); - return true; } case kUpb_CType_Message: PyErr_Format(PyExc_ValueError, "Message objects may not be assigned"); diff --git a/python/convert.h b/python/convert.h index 1c594d3b4a..a2bd2005d1 100644 --- a/python/convert.h +++ b/python/convert.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef PYUPB_CONVERT_H__ #define PYUPB_CONVERT_H__ diff --git a/python/descriptor.c b/python/descriptor.c index be1a839ac2..ea4c028152 100644 --- a/python/descriptor.c +++ b/python/descriptor.c @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "python/descriptor.h" @@ -49,6 +26,7 @@ typedef struct { PyObject* pool; // We own a ref. const void* def; // Type depends on the class. Kept alive by "pool". PyObject* options; // NULL if not present or not cached. + PyObject* features; // NULL if not present or not cached. PyObject* message_meta; // We own a ref. } PyUpb_DescriptorBase; @@ -72,6 +50,7 @@ static PyUpb_DescriptorBase* PyUpb_DescriptorBase_DoCreate( base->pool = PyUpb_DescriptorPool_Get(upb_FileDef_Pool(file)); base->def = def; base->options = NULL; + base->features = NULL; base->message_meta = NULL; PyUpb_ObjCache_Add(def, &base->ob_base); @@ -105,11 +84,12 @@ static PyUpb_DescriptorBase* PyUpb_DescriptorBase_Check( return (PyUpb_DescriptorBase*)obj; } -static PyObject* PyUpb_DescriptorBase_GetOptions(PyUpb_DescriptorBase* self, - const upb_Message* opts, - const upb_MiniTable* layout, - const char* msg_name) { - if (!self->options) { +static PyObject* PyUpb_DescriptorBase_GetCached(PyObject** cached, + const upb_Message* opts, + const upb_MiniTable* layout, + const char* msg_name, + const char* strip_field) { + if (!*cached) { // Load descriptors protos if they are not loaded already. We have to do // this lazily, otherwise, it would lead to circular imports. PyObject* mod = PyImport_ImportModuleLevel(PYUPB_DESCRIPTOR_MODULE, NULL, @@ -142,12 +122,34 @@ static PyObject* PyUpb_DescriptorBase_GetOptions(PyUpb_DescriptorBase* self, (void)ds; assert(ds == kUpb_DecodeStatus_Ok); - self->options = PyUpb_Message_Get(opts2, m, py_arena); + if (strip_field) { + const upb_FieldDef* field = + upb_MessageDef_FindFieldByName(m, strip_field); + assert(field); + upb_Message_ClearFieldByDef(opts2, field); + } + + *cached = PyUpb_Message_Get(opts2, m, py_arena); Py_DECREF(py_arena); } - Py_INCREF(self->options); - return self->options; + Py_INCREF(*cached); + return *cached; +} + +static PyObject* PyUpb_DescriptorBase_GetOptions(PyObject** cached, + const upb_Message* opts, + const upb_MiniTable* layout, + const char* msg_name) { + return PyUpb_DescriptorBase_GetCached(cached, opts, layout, msg_name, + "features"); +} + +static PyObject* PyUpb_DescriptorBase_GetFeatures(PyObject** cached, + const upb_Message* opts) { + return PyUpb_DescriptorBase_GetCached( + cached, opts, &google__protobuf__FeatureSet_msg_init, + PYUPB_DESCRIPTOR_PROTO_PACKAGE ".FeatureSet", NULL); } typedef void* PyUpb_ToProto_Func(const void* def, upb_Arena* arena); @@ -197,10 +199,26 @@ static PyObject* PyUpb_DescriptorBase_CopyToProto(PyObject* _self, } static void PyUpb_DescriptorBase_Dealloc(PyUpb_DescriptorBase* base) { + // This deallocator can be called on different types (which, despite + // 'Base' in the name of one of them, do not inherit from each other). + // Some of these types are GC types (they have Py_TPFLAGS_HAVE_GC set), + // which means Python's GC can visit them (via tp_visit and/or tp_clear + // methods) at any time. This also means we *must* stop GC from tracking + // instances of them before we start destructing the object. In Python + // 3.11, failing to do so would raise a runtime warning. + if (PyType_HasFeature(Py_TYPE(base), Py_TPFLAGS_HAVE_GC)) { + PyObject_GC_UnTrack(base); + } PyUpb_ObjCache_Delete(base->def); - Py_XDECREF(base->message_meta); - Py_DECREF(base->pool); - Py_XDECREF(base->options); + // In addition to being visited by GC, instances can also (potentially) be + // accessed whenever arbitrary code is executed. Destructors can execute + // arbitrary code, so any struct members we DECREF should be set to NULL + // or a new value *before* calling Py_DECREF on them. The Py_CLEAR macro + // (and Py_SETREF in Python 3.8+) takes care to do this safely. + Py_CLEAR(base->message_meta); + Py_CLEAR(base->pool); + Py_CLEAR(base->options); + Py_CLEAR(base->features); PyUpb_Dealloc(base); } @@ -256,9 +274,13 @@ err: void PyUpb_Descriptor_SetClass(PyObject* py_descriptor, PyObject* meta) { PyUpb_DescriptorBase* base = (PyUpb_DescriptorBase*)py_descriptor; - Py_XDECREF(base->message_meta); - base->message_meta = meta; Py_INCREF(meta); + // Py_SETREF replaces strong references without an intermediate invalid + // object state, which code executed by base->message_meta's destructor + // might see, but it's Python 3.8+. + PyObject* tmp = base->message_meta; + base->message_meta = meta; + Py_XDECREF(tmp); } // The LookupNested*() functions provide name lookup for entities nested inside @@ -369,10 +391,17 @@ static PyObject* PyUpb_Descriptor_GetOneofs(PyObject* _self, void* closure) { static PyObject* PyUpb_Descriptor_GetOptions(PyObject* _self, PyObject* args) { PyUpb_DescriptorBase* self = (void*)_self; return PyUpb_DescriptorBase_GetOptions( - self, upb_MessageDef_Options(self->def), &google__protobuf__MessageOptions_msg_init, + &self->options, upb_MessageDef_Options(self->def), + &google__protobuf__MessageOptions_msg_init, PYUPB_DESCRIPTOR_PROTO_PACKAGE ".MessageOptions"); } +static PyObject* PyUpb_Descriptor_GetFeatures(PyObject* _self, PyObject* args) { + PyUpb_DescriptorBase* self = (void*)_self; + return PyUpb_DescriptorBase_GetFeatures( + &self->features, upb_MessageDef_ResolvedFeatures(self->def)); +} + static PyObject* PyUpb_Descriptor_CopyToProto(PyObject* _self, PyObject* py_proto) { return PyUpb_DescriptorBase_CopyToProto( @@ -619,13 +648,6 @@ static PyObject* PyUpb_Descriptor_GetOneofsByName(PyObject* _self, return PyUpb_ByNameMap_New(&funcs, self->def, self->pool); } -static PyObject* PyUpb_Descriptor_GetSyntax(PyObject* self, void* closure) { - const upb_MessageDef* msgdef = PyUpb_Descriptor_GetDef(self); - const char* syntax = - upb_MessageDef_Syntax(msgdef) == kUpb_Syntax_Proto2 ? "proto2" : "proto3"; - return PyUnicode_InternFromString(syntax); -} - static PyGetSetDef PyUpb_Descriptor_Getters[] = { {"name", PyUpb_Descriptor_GetName, NULL, "Last name"}, {"full_name", PyUpb_Descriptor_GetFullName, NULL, "Full name"}, @@ -660,17 +682,11 @@ static PyGetSetDef PyUpb_Descriptor_Getters[] = { "Containing type"}, {"is_extendable", PyUpb_Descriptor_GetIsExtendable, NULL}, {"has_options", PyUpb_Descriptor_GetHasOptions, NULL, "Has Options"}, - // begin:github_only - {"syntax", &PyUpb_Descriptor_GetSyntax, NULL, "Syntax"}, - // end:github_only - // begin:google_only -// // TODO Use this to open-source syntax deprecation. -// {"deprecated_syntax", &PyUpb_Descriptor_GetSyntax, NULL, "Syntax"}, - // end:google_only {NULL}}; static PyMethodDef PyUpb_Descriptor_Methods[] = { {"GetOptions", PyUpb_Descriptor_GetOptions, METH_NOARGS}, + {"_GetFeatures", PyUpb_Descriptor_GetFeatures, METH_NOARGS}, {"CopyToProto", PyUpb_Descriptor_CopyToProto, METH_O}, {"EnumValueName", PyUpb_Descriptor_EnumValueName, METH_VARARGS}, {NULL}}; @@ -793,10 +809,18 @@ static PyObject* PyUpb_EnumDescriptor_GetOptions(PyObject* _self, PyObject* args) { PyUpb_DescriptorBase* self = (void*)_self; return PyUpb_DescriptorBase_GetOptions( - self, upb_EnumDef_Options(self->def), &google__protobuf__EnumOptions_msg_init, + &self->options, upb_EnumDef_Options(self->def), + &google__protobuf__EnumOptions_msg_init, PYUPB_DESCRIPTOR_PROTO_PACKAGE ".EnumOptions"); } +static PyObject* PyUpb_EnumDescriptor_GetFeatures(PyObject* _self, + PyObject* args) { + PyUpb_DescriptorBase* self = (void*)_self; + return PyUpb_DescriptorBase_GetFeatures( + &self->features, upb_EnumDef_ResolvedFeatures(self->def)); +} + static PyObject* PyUpb_EnumDescriptor_CopyToProto(PyObject* _self, PyObject* py_proto) { return PyUpb_DescriptorBase_CopyToProto( @@ -823,6 +847,7 @@ static PyGetSetDef PyUpb_EnumDescriptor_Getters[] = { static PyMethodDef PyUpb_EnumDescriptor_Methods[] = { {"GetOptions", PyUpb_EnumDescriptor_GetOptions, METH_NOARGS}, + {"_GetFeatures", PyUpb_EnumDescriptor_GetFeatures, METH_NOARGS}, {"CopyToProto", PyUpb_EnumDescriptor_CopyToProto, METH_O}, {NULL}}; @@ -883,11 +908,18 @@ static PyObject* PyUpb_EnumValueDescriptor_GetOptions(PyObject* _self, PyObject* args) { PyUpb_DescriptorBase* self = (void*)_self; return PyUpb_DescriptorBase_GetOptions( - self, upb_EnumValueDef_Options(self->def), + &self->options, upb_EnumValueDef_Options(self->def), &google__protobuf__EnumValueOptions_msg_init, PYUPB_DESCRIPTOR_PROTO_PACKAGE ".EnumValueOptions"); } +static PyObject* PyUpb_EnumValueDescriptor_GetFeatures(PyObject* _self, + PyObject* args) { + PyUpb_DescriptorBase* self = (void*)_self; + return PyUpb_DescriptorBase_GetFeatures( + &self->features, upb_EnumValueDef_ResolvedFeatures(self->def)); +} + static PyGetSetDef PyUpb_EnumValueDescriptor_Getters[] = { {"name", PyUpb_EnumValueDescriptor_GetName, NULL, "name"}, {"number", PyUpb_EnumValueDescriptor_GetNumber, NULL, "number"}, @@ -903,6 +935,11 @@ static PyMethodDef PyUpb_EnumValueDescriptor_Methods[] = { PyUpb_EnumValueDescriptor_GetOptions, METH_NOARGS, }, + { + "_GetFeatures", + PyUpb_EnumValueDescriptor_GetFeatures, + METH_NOARGS, + }, {NULL}}; static PyType_Slot PyUpb_EnumValueDescriptor_Slots[] = { @@ -1084,10 +1121,18 @@ static PyObject* PyUpb_FieldDescriptor_GetOptions(PyObject* _self, PyObject* args) { PyUpb_DescriptorBase* self = (void*)_self; return PyUpb_DescriptorBase_GetOptions( - self, upb_FieldDef_Options(self->def), &google__protobuf__FieldOptions_msg_init, + &self->options, upb_FieldDef_Options(self->def), + &google__protobuf__FieldOptions_msg_init, PYUPB_DESCRIPTOR_PROTO_PACKAGE ".FieldOptions"); } +static PyObject* PyUpb_FieldDescriptor_GetFeatures(PyObject* _self, + PyObject* args) { + PyUpb_DescriptorBase* self = (void*)_self; + return PyUpb_DescriptorBase_GetFeatures( + &self->features, upb_FieldDef_ResolvedFeatures(self->def)); +} + static PyGetSetDef PyUpb_FieldDescriptor_Getters[] = { {"full_name", (getter)PyUpb_FieldDescriptor_GetFullName, NULL, "Full name"}, {"name", (getter)PyUpb_FieldDescriptor_GetName, NULL, "Unqualified name"}, @@ -1131,6 +1176,11 @@ static PyMethodDef PyUpb_FieldDescriptor_Methods[] = { PyUpb_FieldDescriptor_GetOptions, METH_NOARGS, }, + { + "_GetFeatures", + PyUpb_FieldDescriptor_GetFeatures, + METH_NOARGS, + }, {NULL}}; static PyType_Slot PyUpb_FieldDescriptor_Slots[] = { @@ -1179,26 +1229,34 @@ static const void* PyUpb_FileDescriptor_NestedLookup( static const void* PyUpb_FileDescriptor_LookupMessage( const upb_FileDef* filedef, const char* name) { - return PyUpb_FileDescriptor_NestedLookup( + const upb_MessageDef* m = PyUpb_FileDescriptor_NestedLookup( filedef, name, (void*)&upb_DefPool_FindMessageByName); + if (!m) return NULL; + return upb_MessageDef_File(m) == filedef ? m : NULL; } static const void* PyUpb_FileDescriptor_LookupEnum(const upb_FileDef* filedef, const char* name) { - return PyUpb_FileDescriptor_NestedLookup(filedef, name, - (void*)&upb_DefPool_FindEnumByName); + const upb_EnumDef* e = PyUpb_FileDescriptor_NestedLookup( + filedef, name, (void*)&upb_DefPool_FindEnumByName); + if (!e) return NULL; + return upb_EnumDef_File(e) == filedef ? e : NULL; } static const void* PyUpb_FileDescriptor_LookupExtension( const upb_FileDef* filedef, const char* name) { - return PyUpb_FileDescriptor_NestedLookup( + const upb_FieldDef* f = PyUpb_FileDescriptor_NestedLookup( filedef, name, (void*)&upb_DefPool_FindExtensionByName); + if (!f) return NULL; + return upb_FieldDef_File(f) == filedef ? f : NULL; } static const void* PyUpb_FileDescriptor_LookupService( const upb_FileDef* filedef, const char* name) { - return PyUpb_FileDescriptor_NestedLookup( + const upb_ServiceDef* s = PyUpb_FileDescriptor_NestedLookup( filedef, name, (void*)&upb_DefPool_FindServiceByName); + if (!s) return NULL; + return upb_ServiceDef_File(s) == filedef ? s : NULL; } static PyObject* PyUpb_FileDescriptor_GetName(PyUpb_DescriptorBase* self, @@ -1307,12 +1365,10 @@ static PyObject* PyUpb_FileDescriptor_GetPublicDependencies(PyObject* _self, return PyUpb_GenericSequence_New(&funcs, self->def, self->pool); } -static PyObject* PyUpb_FileDescriptor_GetSyntax(PyObject* _self, - void* closure) { +static PyObject* PyUpb_FileDescriptor_GetEdition(PyObject* _self, + void* closure) { PyUpb_DescriptorBase* self = (void*)_self; - const char* syntax = - upb_FileDef_Syntax(self->def) == kUpb_Syntax_Proto2 ? "proto2" : "proto3"; - return PyUnicode_FromString(syntax); + return PyLong_FromLong(upb_FileDef_Edition(self->def)); } static PyObject* PyUpb_FileDescriptor_GetHasOptions(PyObject* _self, @@ -1325,10 +1381,18 @@ static PyObject* PyUpb_FileDescriptor_GetOptions(PyObject* _self, PyObject* args) { PyUpb_DescriptorBase* self = (void*)_self; return PyUpb_DescriptorBase_GetOptions( - self, upb_FileDef_Options(self->def), &google__protobuf__FileOptions_msg_init, + &self->options, upb_FileDef_Options(self->def), + &google__protobuf__FileOptions_msg_init, PYUPB_DESCRIPTOR_PROTO_PACKAGE ".FileOptions"); } +static PyObject* PyUpb_FileDescriptor_GetFeatures(PyObject* _self, + PyObject* args) { + PyUpb_DescriptorBase* self = (void*)_self; + return PyUpb_DescriptorBase_GetFeatures( + &self->features, upb_FileDef_ResolvedFeatures(self->def)); +} + static PyObject* PyUpb_FileDescriptor_CopyToProto(PyObject* _self, PyObject* py_proto) { return PyUpb_DescriptorBase_CopyToProto( @@ -1355,19 +1419,13 @@ static PyGetSetDef PyUpb_FileDescriptor_Getters[] = { {"public_dependencies", PyUpb_FileDescriptor_GetPublicDependencies, NULL, "Dependencies"}, {"has_options", PyUpb_FileDescriptor_GetHasOptions, NULL, "Has Options"}, - // begin:github_only - {"syntax", PyUpb_FileDescriptor_GetSyntax, (setter)NULL, "Syntax"}, - // end:github_only - // begin:google_only -// // TODO Use this to open-source syntax deprecation. -// {"deprecated_syntax", PyUpb_FileDescriptor_GetSyntax, (setter)NULL, -// "Syntax"}, - // end:google_only + {"edition", PyUpb_FileDescriptor_GetEdition, (setter)NULL, "Edition"}, {NULL}, }; static PyMethodDef PyUpb_FileDescriptor_Methods[] = { {"GetOptions", PyUpb_FileDescriptor_GetOptions, METH_NOARGS}, + {"_GetFeatures", PyUpb_FileDescriptor_GetFeatures, METH_NOARGS}, {"CopyToProto", PyUpb_FileDescriptor_CopyToProto, METH_O}, {NULL}}; @@ -1457,10 +1515,18 @@ static PyObject* PyUpb_MethodDescriptor_GetOptions(PyObject* _self, PyObject* args) { PyUpb_DescriptorBase* self = (void*)_self; return PyUpb_DescriptorBase_GetOptions( - self, upb_MethodDef_Options(self->def), &google__protobuf__MethodOptions_msg_init, + &self->options, upb_MethodDef_Options(self->def), + &google__protobuf__MethodOptions_msg_init, PYUPB_DESCRIPTOR_PROTO_PACKAGE ".MethodOptions"); } +static PyObject* PyUpb_MethodDescriptor_GetFeatures(PyObject* _self, + PyObject* args) { + PyUpb_DescriptorBase* self = (void*)_self; + return PyUpb_DescriptorBase_GetFeatures( + &self->features, upb_MethodDef_ResolvedFeatures(self->def)); +} + static PyObject* PyUpb_MethodDescriptor_CopyToProto(PyObject* _self, PyObject* py_proto) { return PyUpb_DescriptorBase_CopyToProto( @@ -1487,6 +1553,7 @@ static PyGetSetDef PyUpb_MethodDescriptor_Getters[] = { static PyMethodDef PyUpb_MethodDescriptor_Methods[] = { {"GetOptions", PyUpb_MethodDescriptor_GetOptions, METH_NOARGS}, + {"_GetFeatures", PyUpb_MethodDescriptor_GetFeatures, METH_NOARGS}, {"CopyToProto", PyUpb_MethodDescriptor_CopyToProto, METH_O}, {NULL}}; @@ -1565,10 +1632,18 @@ static PyObject* PyUpb_OneofDescriptor_GetOptions(PyObject* _self, PyObject* args) { PyUpb_DescriptorBase* self = (void*)_self; return PyUpb_DescriptorBase_GetOptions( - self, upb_OneofDef_Options(self->def), &google__protobuf__OneofOptions_msg_init, + &self->options, upb_OneofDef_Options(self->def), + &google__protobuf__OneofOptions_msg_init, PYUPB_DESCRIPTOR_PROTO_PACKAGE ".OneofOptions"); } +static PyObject* PyUpb_OneofDescriptor_GetFeatures(PyObject* _self, + PyObject* args) { + PyUpb_DescriptorBase* self = (void*)_self; + return PyUpb_DescriptorBase_GetFeatures( + &self->features, upb_OneofDef_ResolvedFeatures(self->def)); +} + static PyGetSetDef PyUpb_OneofDescriptor_Getters[] = { {"name", PyUpb_OneofDescriptor_GetName, NULL, "Name"}, {"full_name", PyUpb_OneofDescriptor_GetFullName, NULL, "Full name"}, @@ -1580,7 +1655,9 @@ static PyGetSetDef PyUpb_OneofDescriptor_Getters[] = { {NULL}}; static PyMethodDef PyUpb_OneofDescriptor_Methods[] = { - {"GetOptions", PyUpb_OneofDescriptor_GetOptions, METH_NOARGS}, {NULL}}; + {"GetOptions", PyUpb_OneofDescriptor_GetOptions, METH_NOARGS}, + {"_GetFeatures", PyUpb_OneofDescriptor_GetFeatures, METH_NOARGS}, + {NULL}}; static PyType_Slot PyUpb_OneofDescriptor_Slots[] = { DESCRIPTOR_BASE_SLOTS, @@ -1665,10 +1742,18 @@ static PyObject* PyUpb_ServiceDescriptor_GetOptions(PyObject* _self, PyObject* args) { PyUpb_DescriptorBase* self = (void*)_self; return PyUpb_DescriptorBase_GetOptions( - self, upb_ServiceDef_Options(self->def), &google__protobuf__ServiceOptions_msg_init, + &self->options, upb_ServiceDef_Options(self->def), + &google__protobuf__ServiceOptions_msg_init, PYUPB_DESCRIPTOR_PROTO_PACKAGE ".ServiceOptions"); } +static PyObject* PyUpb_ServiceDescriptor_GetFeatures(PyObject* _self, + PyObject* args) { + PyUpb_DescriptorBase* self = (void*)_self; + return PyUpb_DescriptorBase_GetFeatures( + &self->features, upb_ServiceDef_ResolvedFeatures(self->def)); +} + static PyObject* PyUpb_ServiceDescriptor_CopyToProto(PyObject* _self, PyObject* py_proto) { return PyUpb_DescriptorBase_CopyToProto( @@ -1702,6 +1787,7 @@ static PyGetSetDef PyUpb_ServiceDescriptor_Getters[] = { static PyMethodDef PyUpb_ServiceDescriptor_Methods[] = { {"GetOptions", PyUpb_ServiceDescriptor_GetOptions, METH_NOARGS}, + {"_GetFeatures", PyUpb_ServiceDescriptor_GetFeatures, METH_NOARGS}, {"CopyToProto", PyUpb_ServiceDescriptor_CopyToProto, METH_O}, {"FindMethodByName", PyUpb_ServiceDescriptor_FindMethodByName, METH_O}, {NULL}}; diff --git a/python/descriptor.h b/python/descriptor.h index 7fa0164f0b..013f1d8ca7 100644 --- a/python/descriptor.h +++ b/python/descriptor.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef PYUPB_DESCRIPTOR_H__ #define PYUPB_DESCRIPTOR_H__ diff --git a/python/descriptor_containers.c b/python/descriptor_containers.c index e1eacb2a77..05751a0f89 100644 --- a/python/descriptor_containers.c +++ b/python/descriptor_containers.c @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "python/descriptor_containers.h" diff --git a/python/descriptor_containers.h b/python/descriptor_containers.h index 5b2b1facf6..cd9f8ccb1f 100644 --- a/python/descriptor_containers.h +++ b/python/descriptor_containers.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef PYUPB_DESCRIPTOR_CONTAINERS_H__ #define PYUPB_DESCRIPTOR_CONTAINERS_H__ diff --git a/python/descriptor_pool.c b/python/descriptor_pool.c index ee4167754c..09efbda5fc 100644 --- a/python/descriptor_pool.c +++ b/python/descriptor_pool.c @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "python/descriptor_pool.h" @@ -99,6 +76,7 @@ PyObject* PyUpb_DescriptorPool_Get(const upb_DefPool* symtab) { } static void PyUpb_DescriptorPool_Dealloc(PyUpb_DescriptorPool* self) { + PyObject_GC_UnTrack(self); PyUpb_DescriptorPool_Clear(self); upb_DefPool_Free(self->symtab); PyUpb_ObjCache_Delete(self->symtab); @@ -303,6 +281,48 @@ static PyObject* PyUpb_DescriptorPool_Add(PyObject* _self, return PyUpb_DescriptorPool_DoAdd(_self, file_desc); } +static PyObject* PyUpb_DescriptorPool_SetFeatureSetDefaults( + PyObject* _self, PyObject* defaults) { + if (!PyUpb_Message_Verify(defaults)) { + return PyErr_Format(PyExc_TypeError, + "SetFeatureSetDefaults called with invalid type"); + } + const upb_MessageDef* m = PyUpb_Message_GetMsgdef(defaults); + const char* file_proto_name = + PYUPB_DESCRIPTOR_PROTO_PACKAGE ".FeatureSetDefaults"; + if (strcmp(upb_MessageDef_FullName(m), file_proto_name) != 0) { + return PyErr_Format( + PyExc_TypeError, + "SetFeatureSetDefaults called with invalid type: got %s, expected %s", + upb_MessageDef_FullName(m), file_proto_name); + } + PyObject* subargs = PyTuple_New(0); + if (!subargs) return NULL; + PyObject* py_serialized = + PyUpb_Message_SerializeToString(defaults, subargs, NULL); + Py_DECREF(subargs); + if (!py_serialized) return NULL; + char* serialized; + Py_ssize_t size; + if (PyBytes_AsStringAndSize(py_serialized, &serialized, &size) < 0) { + goto err; + } + + PyUpb_DescriptorPool* self = (PyUpb_DescriptorPool*)_self; + upb_Status status; + if (!upb_DefPool_SetFeatureSetDefaults(self->symtab, serialized, size, + &status)) { + PyErr_SetString(PyExc_ValueError, upb_Status_ErrorMessage(&status)); + goto err; + } + + Py_DECREF(py_serialized); + Py_RETURN_NONE; +err: + Py_DECREF(py_serialized); + return NULL; +} + /* * PyUpb_DescriptorPool_FindFileByName() * @@ -594,6 +614,8 @@ static PyMethodDef PyUpb_DescriptorPool_Methods[] = { "Adds the FileDescriptorProto and its types to this pool."}, {"AddSerializedFile", PyUpb_DescriptorPool_AddSerializedFile, METH_O, "Adds a serialized FileDescriptorProto to this pool."}, + {"SetFeatureSetDefaults", PyUpb_DescriptorPool_SetFeatureSetDefaults, + METH_O, "Sets the default feature mappings used during the build."}, {"FindFileByName", PyUpb_DescriptorPool_FindFileByName, METH_O, "Searches for a file descriptor by its .proto name."}, {"FindMessageTypeByName", PyUpb_DescriptorPool_FindMessageTypeByName, diff --git a/python/descriptor_pool.h b/python/descriptor_pool.h index ae50ef0199..2283b96f5e 100644 --- a/python/descriptor_pool.h +++ b/python/descriptor_pool.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef PYUPB_DESCRIPTOR_POOL_H__ #define PYUPB_DESCRIPTOR_POOL_H__ diff --git a/python/dist/BUILD.bazel b/python/dist/BUILD.bazel index 4330fe1c4f..34f32452bb 100644 --- a/python/dist/BUILD.bazel +++ b/python/dist/BUILD.bazel @@ -5,6 +5,7 @@ # license that can be found in the LICENSE file or at # https://developers.google.com/open-source/licenses/bsd +load("@pip_deps//:requirements.bzl", "requirement") load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") load("@rules_pkg//:pkg.bzl", "pkg_tar") load("@rules_python//python:packaging.bzl", "py_wheel") @@ -216,7 +217,7 @@ pkg_files( pkg_files( name = "utf8_range_source_files", - srcs = ["@utf8_range//:utf8_range_srcs"], + srcs = ["//third_party/utf8_range:utf8_range_srcs"], prefix = "utf8_range", ) @@ -246,6 +247,7 @@ pkg_files( "//upb/mini_descriptor:source_files", "//upb/mini_table:source_files", "//upb/port:source_files", + "//upb/reflection:source_files", "//upb/text:source_files", "//upb/util:source_files", "//upb/wire:source_files", @@ -280,6 +282,7 @@ genrule( srcs = [":source_tarball"], outs = ["protobuf-%s.tar.gz" % PROTOBUF_PYTHON_VERSION], cmd = """ + export PYTHONPATH=$$PWD/external/pip_deps_setuptools/site-packages set -eux tar -xzvf $(location :source_tarball) cd protobuf/ @@ -291,6 +294,7 @@ genrule( "@system_python//:none": ["@platforms//:incompatible"], "//conditions:default": [], }), + tools = [requirement("setuptools")], ) py_wheel( @@ -309,6 +313,7 @@ py_wheel( "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ], distribution = "protobuf", extra_distinfo_files = { @@ -364,6 +369,7 @@ py_wheel( "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ], distribution = "protobuf", extra_distinfo_files = { diff --git a/python/dist/setup.py b/python/dist/setup.py index 8d05011b53..534e3fb5cd 100755 --- a/python/dist/setup.py +++ b/python/dist/setup.py @@ -58,6 +58,7 @@ setup( 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', ], namespace_packages=['google'], packages=find_packages(), diff --git a/python/extension_dict.c b/python/extension_dict.c index d4b4ddadac..34e1f9bd29 100644 --- a/python/extension_dict.c +++ b/python/extension_dict.c @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "python/extension_dict.h" diff --git a/python/extension_dict.h b/python/extension_dict.h index 99d2addf23..9db01cdf1e 100644 --- a/python/extension_dict.h +++ b/python/extension_dict.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef PYUPB_EXTENSION_DICT_H__ #define PYUPB_EXTENSION_DICT_H__ diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py index 45a6c20c59..522b7ed499 100755 --- a/python/google/protobuf/__init__.py +++ b/python/google/protobuf/__init__.py @@ -7,4 +7,4 @@ # Copyright 2007 Google Inc. All Rights Reserved. -__version__ = '4.24.0' +__version__ = '4.25.0' diff --git a/python/google/protobuf/descriptor.py b/python/google/protobuf/descriptor.py index f8b12ff132..29885ff395 100755 --- a/python/google/protobuf/descriptor.py +++ b/python/google/protobuf/descriptor.py @@ -11,6 +11,9 @@ file, in types that make this information accessible in Python. __author__ = 'robinson@google.com (Will Robinson)' +import abc +import binascii +import os import threading import warnings @@ -18,9 +21,6 @@ from google.protobuf.internal import api_implementation _USE_C_DESCRIPTORS = False if api_implementation.Type() != 'python': - # Used by MakeDescriptor in cpp mode - import binascii - import os # pylint: disable=protected-access _message = api_implementation._c_module # TODO: Remove this import after fix api_implementation @@ -52,7 +52,7 @@ if _USE_C_DESCRIPTORS: return False else: # The standard metaclass; nothing changes. - DescriptorMetaclass = type + DescriptorMetaclass = abc.ABCMeta class _Lock(object): @@ -83,6 +83,14 @@ def _Deprecated(name): % name, category=DeprecationWarning, stacklevel=3) +# These must match the values in descriptor.proto, but we can't use them +# directly because we sometimes need to reference them in feature helpers +# below *during* the build of descriptor.proto. +_FEATURESET_MESSAGE_ENCODING_DELIMITED = 2 +_FEATURESET_FIELD_PRESENCE_IMPLICIT = 2 +_FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED = 3 +_FEATURESET_REPEATED_FIELD_ENCODING_PACKED = 1 +_FEATURESET_ENUM_TYPE_CLOSED = 2 # Deprecated warnings will print 100 times at most which should be enough for # users to notice and do not cause timeout. @@ -118,8 +126,10 @@ class DescriptorBase(metaclass=DescriptorMetaclass): class of the options message. The name of the class is required in case the options message is None and has to be created. """ + self._features = None self.file = file self._options = options + self._loaded_options = None self._options_class_name = options_class_name self._serialized_options = serialized_options @@ -128,44 +138,106 @@ class DescriptorBase(metaclass=DescriptorMetaclass): self._serialized_options is not None ) - def _SetOptions(self, options, options_class_name): - """Sets the descriptor's options + @property + @abc.abstractmethod + def _parent(self): + pass + + def _InferLegacyFeatures(self, edition, options, features): + """Infers features from proto2/proto3 syntax so that editions logic can be used everywhere. - This function is used in generated proto2 files to update descriptor - options. It must not be used outside proto2. + Args: + edition: The edition to infer features for. + options: The options for this descriptor that are being processed. + features: The feature set object to modify with inferred features. """ - self._options = options - self._options_class_name = options_class_name + pass - # Does this descriptor have non-default options? - self.has_options = options is not None + def _GetFeatures(self): + if not self._features: + self._LazyLoadOptions() + return self._features - def GetOptions(self): - """Retrieves descriptor options. + def _ResolveFeatures(self, edition, raw_options): + """Resolves features from the raw options of this descriptor. - This method returns the options set or creates the default options for the - descriptor. + Args: + edition: The edition to use for feature defaults. + raw_options: The options for this descriptor that are being processed. + + Returns: + A fully resolved feature set for making runtime decisions. """ - if self._options: - return self._options + # pylint: disable=g-import-not-at-top + from google.protobuf import descriptor_pb2 + + if self._parent: + features = descriptor_pb2.FeatureSet() + features.CopyFrom(self._parent._GetFeatures()) + else: + features = self.file.pool._CreateDefaultFeatures(edition) + unresolved = descriptor_pb2.FeatureSet() + unresolved.CopyFrom(raw_options.features) + self._InferLegacyFeatures(edition, raw_options, unresolved) + features.MergeFrom(unresolved) + + # Use the feature cache to reduce memory bloat. + return self.file.pool._InternFeatures(features) + + def _LazyLoadOptions(self): + """Lazily initializes descriptor options towards the end of the build.""" + if self._loaded_options: + return + # pylint: disable=g-import-not-at-top from google.protobuf import descriptor_pb2 - try: - options_class = getattr(descriptor_pb2, - self._options_class_name) - except AttributeError: - raise RuntimeError('Unknown options class name %s!' % - (self._options_class_name)) - if self._serialized_options is None: + if not hasattr(descriptor_pb2, self._options_class_name): + raise RuntimeError( + 'Unknown options class name %s!' % self._options_class_name + ) + options_class = getattr(descriptor_pb2, self._options_class_name) + features = None + edition = self.file._edition + + if not self.has_options: + if not self._features: + features = self._ResolveFeatures( + descriptor_pb2.Edition.Value(edition), options_class() + ) with _lock: - self._options = options_class() + self._loaded_options = options_class() + if not self._features: + self._features = features else: - options = _ParseOptions(options_class(), self._serialized_options) + if not self._serialized_options: + options = self._options + else: + options = _ParseOptions(options_class(), self._serialized_options) + + if not self._features: + features = self._ResolveFeatures( + descriptor_pb2.Edition.Value(edition), options + ) with _lock: - self._options = options + self._loaded_options = options + if not self._features: + self._features = features + if options.HasField('features'): + options.ClearField('features') + if not options.SerializeToString(): + self._loaded_options = options_class() + self.has_options = False - return self._options + def GetOptions(self): + """Retrieves descriptor options. + + Returns: + The options set on this descriptor. + """ + if not self._loaded_options: + self._LazyLoadOptions() + return self._loaded_options class _NestedDescriptorBase(DescriptorBase): @@ -327,6 +399,7 @@ class Descriptor(_NestedDescriptorBase): self.fields = fields for field in self.fields: field.containing_type = self + field.file = file self.fields_by_number = dict((f.number, f) for f in fields) self.fields_by_name = dict((f.name, f) for f in fields) self._fields_by_camelcase_name = None @@ -353,9 +426,13 @@ class Descriptor(_NestedDescriptorBase): self.oneofs_by_name = dict((o.name, o) for o in self.oneofs) for oneof in self.oneofs: oneof.containing_type = self - self.syntax = syntax or "proto2" + oneof.file = file self._is_map_entry = is_map_entry + @property + def _parent(self): + return self.containing_type or self.file + @property def fields_by_camelcase_name(self): """Same FieldDescriptor objects as in :attr:`fields`, but indexed by @@ -575,9 +652,9 @@ class FieldDescriptor(DescriptorBase): self.json_name = json_name self.index = index self.number = number - self.type = type + self._type = type self.cpp_type = cpp_type - self.label = label + self._label = label self.has_default_value = has_default_value self.default_value = default_value self.containing_type = containing_type @@ -594,6 +671,60 @@ class FieldDescriptor(DescriptorBase): else: self._cdescriptor = _message.default_pool.FindFieldByName(full_name) + @property + def _parent(self): + if self.containing_oneof: + return self.containing_oneof + if self.is_extension: + return self.extension_scope or self.file + return self.containing_type + + def _InferLegacyFeatures(self, edition, options, features): + # pylint: disable=g-import-not-at-top + from google.protobuf import descriptor_pb2 + + if edition >= descriptor_pb2.Edition.EDITION_2023: + return + + if self._label == FieldDescriptor.LABEL_REQUIRED: + features.field_presence = ( + descriptor_pb2.FeatureSet.FieldPresence.LEGACY_REQUIRED + ) + + if self._type == FieldDescriptor.TYPE_GROUP: + features.message_encoding = ( + descriptor_pb2.FeatureSet.MessageEncoding.DELIMITED + ) + + if options.HasField('packed'): + features.repeated_field_encoding = ( + descriptor_pb2.FeatureSet.RepeatedFieldEncoding.PACKED + if options.packed + else descriptor_pb2.FeatureSet.RepeatedFieldEncoding.EXPANDED + ) + + @property + def type(self): + if ( + self._GetFeatures().message_encoding + == _FEATURESET_MESSAGE_ENCODING_DELIMITED + ): + return FieldDescriptor.TYPE_GROUP + return self._type + + @type.setter + def type(self, val): + self._type = val + + @property + def label(self): + if ( + self._GetFeatures().field_presence + == _FEATURESET_FIELD_PRESENCE_LEGACY_REQUIRED + ): + return FieldDescriptor.LABEL_REQUIRED + return self._label + @property def camelcase_name(self): """Camelcase name of this field. @@ -617,11 +748,11 @@ class FieldDescriptor(DescriptorBase): if (self.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE or self.containing_oneof): return True - # self.containing_type is used here instead of self.file for legacy - # compatibility. FieldDescriptor.file was added in cl/153110619 - # Some old/generated code didn't link file to FieldDescriptor. - # TODO: remove syntax usage b/240619313 - return self.containing_type.syntax == 'proto2' + + return ( + self._GetFeatures().field_presence + != _FEATURESET_FIELD_PRESENCE_IMPLICIT + ) @property def is_packed(self): @@ -634,12 +765,11 @@ class FieldDescriptor(DescriptorBase): field_type == FieldDescriptor.TYPE_MESSAGE or field_type == FieldDescriptor.TYPE_BYTES): return False - if self.containing_type.syntax == 'proto2': - return self.has_options and self.GetOptions().packed - else: - return (not self.has_options or - not self.GetOptions().HasField('packed') or - self.GetOptions().packed) + + return ( + self._GetFeatures().repeated_field_encoding + == _FEATURESET_REPEATED_FIELD_ENCODING_PACKED + ) @staticmethod def ProtoTypeToCppProtoType(proto_type): @@ -721,6 +851,10 @@ class EnumDescriptor(_NestedDescriptorBase): # Values are reversed to ensure that the first alias is retained. self.values_by_number = dict((v.number, v) for v in reversed(values)) + @property + def _parent(self): + return self.containing_type or self.file + @property def is_closed(self): """Returns true whether this is a "closed" enum. @@ -743,7 +877,7 @@ class EnumDescriptor(_NestedDescriptorBase): Care should be taken when using this function to respect the target runtime's enum handling quirks. """ - return self.file.syntax == 'proto2' + return self._GetFeatures().enum_type == _FEATURESET_ENUM_TYPE_CLOSED def CopyToProto(self, proto): """Copies this to a descriptor_pb2.EnumDescriptorProto. @@ -802,6 +936,10 @@ class EnumValueDescriptor(DescriptorBase): self.number = number self.type = type + @property + def _parent(self): + return self.type + class OneofDescriptor(DescriptorBase): """Descriptor for a oneof field. @@ -846,6 +984,10 @@ class OneofDescriptor(DescriptorBase): self.containing_type = containing_type self.fields = fields + @property + def _parent(self): + return self.containing_type + class ServiceDescriptor(_NestedDescriptorBase): @@ -902,6 +1044,10 @@ class ServiceDescriptor(_NestedDescriptorBase): method.file = self.file method.containing_service = self + @property + def _parent(self): + return self.file + def FindMethodByName(self, name): """Searches for the specified method, and returns its descriptor. @@ -999,6 +1145,10 @@ class MethodDescriptor(DescriptorBase): self.client_streaming = client_streaming self.server_streaming = server_streaming + @property + def _parent(self): + return self.containing_service + def CopyToProto(self, proto): """Copies this to a descriptor_pb2.MethodDescriptorProto. @@ -1029,33 +1179,42 @@ class FileDescriptor(DescriptorBase): Attributes: name (str): Name of file, relative to root of source tree. package (str): Name of the package - syntax (str): string indicating syntax of the file (can be "proto2" or - "proto3") + edition (Edition): Enum value indicating edition of the file serialized_pb (bytes): Byte string of serialized :class:`descriptor_pb2.FileDescriptorProto`. dependencies (list[FileDescriptor]): List of other :class:`FileDescriptor` objects this :class:`FileDescriptor` depends on. public_dependencies (list[FileDescriptor]): A subset of :attr:`dependencies`, which were declared as "public". - message_types_by_name (dict(str, Descriptor)): Mapping from message names - to their :class:`Descriptor`. + message_types_by_name (dict(str, Descriptor)): Mapping from message names to + their :class:`Descriptor`. enum_types_by_name (dict(str, EnumDescriptor)): Mapping from enum names to their :class:`EnumDescriptor`. extensions_by_name (dict(str, FieldDescriptor)): Mapping from extension names declared at file scope to their :class:`FieldDescriptor`. services_by_name (dict(str, ServiceDescriptor)): Mapping from services' names to their :class:`ServiceDescriptor`. - pool (DescriptorPool): The pool this descriptor belongs to. When not - passed to the constructor, the global default pool is used. + pool (DescriptorPool): The pool this descriptor belongs to. When not passed + to the constructor, the global default pool is used. """ if _USE_C_DESCRIPTORS: _C_DESCRIPTOR_CLASS = _message.FileDescriptor - def __new__(cls, name, package, options=None, - serialized_options=None, serialized_pb=None, - dependencies=None, public_dependencies=None, - syntax=None, pool=None, create_key=None): + def __new__( + cls, + name, + package, + options=None, + serialized_options=None, + serialized_pb=None, + dependencies=None, + public_dependencies=None, + syntax=None, + edition=None, + pool=None, + create_key=None, + ): # FileDescriptor() is called from various places, not only from generated # files, to register dynamic proto files and messages. # pylint: disable=g-explicit-bool-comparison @@ -1064,18 +1223,35 @@ class FileDescriptor(DescriptorBase): else: return super(FileDescriptor, cls).__new__(cls) - def __init__(self, name, package, options=None, - serialized_options=None, serialized_pb=None, - dependencies=None, public_dependencies=None, - syntax=None, pool=None, create_key=None): + def __init__( + self, + name, + package, + options=None, + serialized_options=None, + serialized_pb=None, + dependencies=None, + public_dependencies=None, + syntax=None, + edition=None, + pool=None, + create_key=None, + ): """Constructor.""" if create_key is not _internal_create_key: _Deprecated('FileDescriptor') super(FileDescriptor, self).__init__( - None, options, serialized_options, 'FileOptions' + self, options, serialized_options, 'FileOptions' ) + if edition and edition != 'EDITION_UNKNOWN': + self._edition = edition + elif syntax == 'proto3': + self._edition = 'EDITION_PROTO3' + else: + self._edition = 'EDITION_PROTO2' + if pool is None: from google.protobuf import descriptor_pool pool = descriptor_pool.Default() @@ -1083,7 +1259,6 @@ class FileDescriptor(DescriptorBase): self.message_types_by_name = {} self.name = name self.package = package - self.syntax = syntax or "proto2" self.serialized_pb = serialized_pb self.enum_types_by_name = {} @@ -1100,6 +1275,17 @@ class FileDescriptor(DescriptorBase): """ proto.ParseFromString(self.serialized_pb) + @property + def _parent(self): + return None + + @property + def edition(self): + # pylint: disable=g-import-not-at-top + from google.protobuf import descriptor_pb2 + + return descriptor_pb2.Edition.Value(self._edition) + def _ParseOptions(message, string): """Parses serialized options. @@ -1157,8 +1343,14 @@ def _ToJsonName(name): return ''.join(result) -def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True, - syntax=None): +def MakeDescriptor( + desc_proto, + package='', + build_file_if_cpp=True, + syntax=None, + edition=None, + file_desc=None, +): """Make a protobuf Descriptor given a DescriptorProto protobuf. Handles nested descriptors. Note that this is limited to the scope of defining @@ -1168,34 +1360,41 @@ def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True, Args: desc_proto: The descriptor_pb2.DescriptorProto protobuf message. package: Optional package name for the new message Descriptor (string). - build_file_if_cpp: Update the C++ descriptor pool if api matches. - Set to False on recursion, so no duplicates are created. + build_file_if_cpp: Update the C++ descriptor pool if api matches. Set to + False on recursion, so no duplicates are created. syntax: The syntax/semantics that should be used. Set to "proto3" to get - proto3 field presence semantics. + proto3 field presence semantics. + edition: The edition that should be used if syntax is "edition". + file_desc: A FileDescriptor to place this descriptor into. + Returns: A Descriptor for protobuf messages. """ + # pylint: disable=g-import-not-at-top + from google.protobuf import descriptor_pb2 + + # Generate a random name for this proto file to prevent conflicts with any + # imported ones. We need to specify a file name so the descriptor pool + # accepts our FileDescriptorProto, but it is not important what that file + # name is actually set to. + proto_name = binascii.hexlify(os.urandom(16)).decode('ascii') + + if package: + file_name = os.path.join(package.replace('.', '/'), proto_name + '.proto') + else: + file_name = proto_name + '.proto' + if api_implementation.Type() != 'python' and build_file_if_cpp: # The C++ implementation requires all descriptors to be backed by the same # definition in the C++ descriptor pool. To do this, we build a # FileDescriptorProto with the same definition as this descriptor and build # it into the pool. - from google.protobuf import descriptor_pb2 file_descriptor_proto = descriptor_pb2.FileDescriptorProto() file_descriptor_proto.message_type.add().MergeFrom(desc_proto) - # Generate a random name for this proto file to prevent conflicts with any - # imported ones. We need to specify a file name so the descriptor pool - # accepts our FileDescriptorProto, but it is not important what that file - # name is actually set to. - proto_name = binascii.hexlify(os.urandom(16)).decode('ascii') - if package: - file_descriptor_proto.name = os.path.join(package.replace('.', '/'), - proto_name + '.proto') file_descriptor_proto.package = package - else: - file_descriptor_proto.name = proto_name + '.proto' + file_descriptor_proto.name = file_name _message.default_pool.Add(file_descriptor_proto) result = _message.default_pool.FindFileByName(file_descriptor_proto.name) @@ -1203,6 +1402,19 @@ def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True, if _USE_C_DESCRIPTORS: return result.message_types_by_name[desc_proto.name] + if file_desc is None: + file_desc = FileDescriptor( + pool=None, + name=file_name, + package=package, + syntax=syntax, + edition=edition, + options=None, + serialized_pb='', + dependencies=[], + public_dependencies=[], + create_key=_internal_create_key, + ) full_message_name = [desc_proto.name] if package: full_message_name.insert(0, package) @@ -1211,11 +1423,21 @@ def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True, for enum_proto in desc_proto.enum_type: full_name = '.'.join(full_message_name + [enum_proto.name]) enum_desc = EnumDescriptor( - enum_proto.name, full_name, None, [ - EnumValueDescriptor(enum_val.name, ii, enum_val.number, - create_key=_internal_create_key) - for ii, enum_val in enumerate(enum_proto.value)], - create_key=_internal_create_key) + enum_proto.name, + full_name, + None, + [ + EnumValueDescriptor( + enum_val.name, + ii, + enum_val.number, + create_key=_internal_create_key, + ) + for ii, enum_val in enumerate(enum_proto.value) + ], + file=file_desc, + create_key=_internal_create_key, + ) enum_types[full_name] = enum_desc # Create Descriptors for nested types @@ -1224,10 +1446,14 @@ def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True, full_name = '.'.join(full_message_name + [nested_proto.name]) # Nested types are just those defined inside of the message, not all types # used by fields in the message, so no loops are possible here. - nested_desc = MakeDescriptor(nested_proto, - package='.'.join(full_message_name), - build_file_if_cpp=False, - syntax=syntax) + nested_desc = MakeDescriptor( + nested_proto, + package='.'.join(full_message_name), + build_file_if_cpp=False, + syntax=syntax, + edition=edition, + file_desc=file_desc, + ) nested_types[full_name] = nested_desc fields = [] @@ -1249,16 +1475,38 @@ def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True, enum_desc = enum_types[full_type_name] # Else type_name references a non-local type, which isn't implemented field = FieldDescriptor( - field_proto.name, full_name, field_proto.number - 1, - field_proto.number, field_proto.type, + field_proto.name, + full_name, + field_proto.number - 1, + field_proto.number, + field_proto.type, FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type), - field_proto.label, None, nested_desc, enum_desc, None, False, None, - options=_OptionsOrNone(field_proto), has_default_value=False, - json_name=json_name, create_key=_internal_create_key) + field_proto.label, + None, + nested_desc, + enum_desc, + None, + False, + None, + options=_OptionsOrNone(field_proto), + has_default_value=False, + json_name=json_name, + file=file_desc, + create_key=_internal_create_key, + ) fields.append(field) desc_name = '.'.join(full_message_name) - return Descriptor(desc_proto.name, desc_name, None, None, fields, - list(nested_types.values()), list(enum_types.values()), [], - options=_OptionsOrNone(desc_proto), - create_key=_internal_create_key) + return Descriptor( + desc_proto.name, + desc_name, + None, + None, + fields, + list(nested_types.values()), + list(enum_types.values()), + [], + options=_OptionsOrNone(desc_proto), + file=file_desc, + create_key=_internal_create_key, + ) diff --git a/python/google/protobuf/descriptor_pool.py b/python/google/protobuf/descriptor_pool.py index c2fe59fdcd..bf3476feec 100644 --- a/python/google/protobuf/descriptor_pool.py +++ b/python/google/protobuf/descriptor_pool.py @@ -35,11 +35,13 @@ directly instead of this class. __author__ = 'matthewtoia@google.com (Matt Toia)' import collections +import threading import warnings from google.protobuf import descriptor from google.protobuf import descriptor_database from google.protobuf import text_encoding +from google.protobuf.internal import python_edition_defaults from google.protobuf.internal import python_message _USE_C_DESCRIPTORS = descriptor._USE_C_DESCRIPTORS # pylint: disable=protected-access @@ -91,6 +93,8 @@ def _IsMessageSetExtension(field): field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL) +_edition_defaults_lock = threading.Lock() + class DescriptorPool(object): """A collection of protobufs dynamically constructed by descriptor protos.""" @@ -131,6 +135,11 @@ class DescriptorPool(object): # full name or its tag number. self._extensions_by_name = collections.defaultdict(dict) self._extensions_by_number = collections.defaultdict(dict) + self._serialized_edition_defaults = ( + python_edition_defaults._PROTOBUF_INTERNAL_PYTHON_EDITION_DEFAULTS + ) + self._edition_defaults = None + self._feature_cache = dict() def _CheckConflictRegister(self, desc, desc_name, file_name): """Check if the descriptor name conflicts with another of the same name. @@ -679,6 +688,113 @@ class DescriptorPool(object): service_descriptor = self.FindServiceByName(service_name) return service_descriptor.methods_by_name[method_name] + def SetFeatureSetDefaults(self, defaults): + """Sets the default feature mappings used during the build. + + Args: + defaults: a FeatureSetDefaults message containing the new mappings. + """ + if self._edition_defaults is not None: + raise ValueError( + "Feature set defaults can't be changed once the pool has started" + ' building!' + ) + + # pylint: disable=g-import-not-at-top + from google.protobuf import descriptor_pb2 + + if not isinstance(defaults, descriptor_pb2.FeatureSetDefaults): + raise TypeError('SetFeatureSetDefaults called with invalid type') + + + if defaults.minimum_edition > defaults.maximum_edition: + raise ValueError( + 'Invalid edition range %s to %s' + % ( + descriptor_pb2.Edition.Name(defaults.minimum_edition), + descriptor_pb2.Edition.Name(defaults.maximum_edition), + ) + ) + + prev_edition = descriptor_pb2.Edition.EDITION_UNKNOWN + for d in defaults.defaults: + if d.edition == descriptor_pb2.Edition.EDITION_UNKNOWN: + raise ValueError('Invalid edition EDITION_UNKNOWN specified') + if prev_edition >= d.edition: + raise ValueError( + 'Feature set defaults are not strictly increasing. %s is greater' + ' than or equal to %s' + % ( + descriptor_pb2.Edition.Name(prev_edition), + descriptor_pb2.Edition.Name(d.edition), + ) + ) + prev_edition = d.edition + self._edition_defaults = defaults + + def _CreateDefaultFeatures(self, edition): + """Creates a FeatureSet message with defaults for a specific edition. + + Args: + edition: the edition to generate defaults for. + + Returns: + A FeatureSet message with defaults for a specific edition. + """ + # pylint: disable=g-import-not-at-top + from google.protobuf import descriptor_pb2 + + with _edition_defaults_lock: + if not self._edition_defaults: + self._edition_defaults = descriptor_pb2.FeatureSetDefaults() + self._edition_defaults.ParseFromString( + self._serialized_edition_defaults + ) + + if edition < self._edition_defaults.minimum_edition: + raise TypeError( + 'Edition %s is earlier than the minimum supported edition %s!' + % ( + descriptor_pb2.Edition.Name(edition), + descriptor_pb2.Edition.Name( + self._edition_defaults.minimum_edition + ), + ) + ) + if edition > self._edition_defaults.maximum_edition: + raise TypeError( + 'Edition %s is later than the maximum supported edition %s!' + % ( + descriptor_pb2.Edition.Name(edition), + descriptor_pb2.Edition.Name( + self._edition_defaults.maximum_edition + ), + ) + ) + found = None + for d in self._edition_defaults.defaults: + if d.edition > edition: + break + found = d.features + if found is None: + raise TypeError( + 'No valid default found for edition %s!' + % descriptor_pb2.Edition.Name(edition) + ) + + defaults = descriptor_pb2.FeatureSet() + defaults.CopyFrom(found) + return defaults + + def _InternFeatures(self, features): + serialized = features.SerializeToString() + with _edition_defaults_lock: + cached = self._feature_cache.get(serialized) + if cached is None: + self._feature_cache[serialized] = features + cached = features + return cached + def _FindFileContainingSymbolInDb(self, symbol): """Finds the file in descriptor DB containing the specified symbol. @@ -719,17 +835,22 @@ class DescriptorPool(object): direct_deps = [self.FindFileByName(n) for n in file_proto.dependency] public_deps = [direct_deps[i] for i in file_proto.public_dependency] + # pylint: disable=g-import-not-at-top + from google.protobuf import descriptor_pb2 + file_descriptor = descriptor.FileDescriptor( pool=self, name=file_proto.name, package=file_proto.package, syntax=file_proto.syntax, + edition=descriptor_pb2.Edition.Name(file_proto.edition), options=_OptionsOrNone(file_proto), serialized_pb=file_proto.SerializeToString(), dependencies=direct_deps, public_dependencies=public_deps, # pylint: disable=protected-access - create_key=descriptor._internal_create_key) + create_key=descriptor._internal_create_key, + ) scope = {} # This loop extracts all the message and enum types from all the @@ -876,10 +997,10 @@ class DescriptorPool(object): file=file_desc, serialized_start=None, serialized_end=None, - syntax=syntax, is_map_entry=desc_proto.options.map_entry, # pylint: disable=protected-access - create_key=descriptor._internal_create_key) + create_key=descriptor._internal_create_key, + ) for nested in desc.nested_types: nested.containing_type = desc for enum in desc.enum_types: diff --git a/python/google/protobuf/internal/api_implementation.py b/python/google/protobuf/internal/api_implementation.py index 65caf63f8b..09af96e67c 100755 --- a/python/google/protobuf/internal/api_implementation.py +++ b/python/google/protobuf/internal/api_implementation.py @@ -13,6 +13,8 @@ import os import sys import warnings +_GOOGLE3_PYTHON_UPB_DEFAULT = False + def _ApiVersionToImplementationType(api_version): if api_version == 2: diff --git a/python/google/protobuf/internal/descriptor_pool_test.py b/python/google/protobuf/internal/descriptor_pool_test.py index dd2dc32423..8f3bdeb2f9 100644 --- a/python/google/protobuf/internal/descriptor_pool_test.py +++ b/python/google/protobuf/internal/descriptor_pool_test.py @@ -13,7 +13,12 @@ import copy import unittest import warnings +from google.protobuf import descriptor +from google.protobuf import descriptor_database from google.protobuf import descriptor_pb2 +from google.protobuf import descriptor_pool +from google.protobuf import message_factory +from google.protobuf import symbol_database from google.protobuf.internal import api_implementation from google.protobuf.internal import descriptor_pool_test1_pb2 from google.protobuf.internal import descriptor_pool_test2_pb2 @@ -23,15 +28,15 @@ from google.protobuf.internal import file_options_test_pb2 from google.protobuf.internal import more_messages_pb2 from google.protobuf.internal import no_package_pb2 from google.protobuf.internal import testing_refleaks -from google.protobuf import descriptor -from google.protobuf import descriptor_database -from google.protobuf import descriptor_pool -from google.protobuf import message_factory -from google.protobuf import symbol_database + +from google.protobuf import unittest_features_pb2 from google.protobuf import unittest_import_pb2 from google.protobuf import unittest_import_public_pb2 from google.protobuf import unittest_pb2 +# pyformat: disable +# pyformat: enable + warnings.simplefilter('error', DeprecationWarning) @@ -127,6 +132,51 @@ class DescriptorPoolTestBase(object): self.assertRaises(KeyError, self.pool.FindFileContainingSymbol, 'google.protobuf.python.internal.Factory1Message.none_field') + def testCrossFileMessageTypesByName(self): + self.assertIs( + descriptor_pool_test1_pb2.DescriptorPoolTest1.DESCRIPTOR, + descriptor_pool_test1_pb2.DESCRIPTOR.message_types_by_name[ + 'DescriptorPoolTest1' + ], + ) + with self.assertRaises(KeyError): + descriptor_pool_test2_pb2.DESCRIPTOR.message_types_by_name[ + 'DescriptorPoolTest1' + ] + + def testCrossFileEnumTypesByName(self): + self.assertIs( + descriptor_pool_test1_pb2.TopLevelEnumTest1.DESCRIPTOR, + descriptor_pool_test1_pb2.DESCRIPTOR.enum_types_by_name[ + 'TopLevelEnumTest1' + ], + ) + with self.assertRaises(KeyError): + descriptor_pool_test2_pb2.DESCRIPTOR.enum_types_by_name[ + 'TopLevelEnumTest1' + ] + + def testCrossFileExtensionsByName(self): + self.assertIs( + descriptor_pool_test1_pb2.top_level_extension_test1, + descriptor_pool_test1_pb2.DESCRIPTOR.extensions_by_name[ + 'top_level_extension_test1' + ], + ) + with self.assertRaises(KeyError): + descriptor_pool_test2_pb2.DESCRIPTOR.extensions_by_name[ + 'top_level_extension_test1' + ] + + def testCrossFileServicesByName(self): + descriptor_pool_test1_pb2.DESCRIPTOR.services_by_name[ + 'DescriporPoolTestService' + ], + with self.assertRaises(KeyError): + descriptor_pool_test2_pb2.DESCRIPTOR.services_by_name[ + 'DescriporPoolTestService' + ] + def testFindFileContainingSymbolFailure(self): with self.assertRaises(KeyError): self.pool.FindFileContainingSymbol('Does not exist') @@ -1070,6 +1120,206 @@ class AddDescriptorTest(unittest.TestCase): pool._AddFileDescriptor(0) +@testing_refleaks.TestCase +class FeatureSetDefaults(unittest.TestCase): + + def testDefault(self): + pool = descriptor_pool.DescriptorPool() + file_desc = descriptor_pb2.FileDescriptorProto(name='some/file.proto') + file = pool.AddSerializedFile(file_desc.SerializeToString()) + self.assertFalse( + file._GetFeatures().HasExtension(unittest_features_pb2.test) + ) + + def testOverride(self): + pool = descriptor_pool.DescriptorPool() + defaults = descriptor_pb2.FeatureSetDefaults( + defaults=[ + descriptor_pb2.FeatureSetDefaults.FeatureSetEditionDefault( + edition=descriptor_pb2.Edition.EDITION_PROTO2, + features=unittest_features_pb2.DESCRIPTOR._GetFeatures(), + ) + ], + minimum_edition=descriptor_pb2.Edition.EDITION_PROTO2, + maximum_edition=descriptor_pb2.Edition.EDITION_2023, + ) + defaults.defaults[0].features.Extensions[ + unittest_features_pb2.test + ].int_file_feature = 9 + pool.SetFeatureSetDefaults(defaults) + file_desc = descriptor_pb2.FileDescriptorProto(name='some/file.proto') + file = pool.AddSerializedFile(file_desc.SerializeToString()) + self.assertTrue( + file._GetFeatures().HasExtension(unittest_features_pb2.test) + ) + + def testInvalidType(self): + pool = descriptor_pool.DescriptorPool() + with self.assertRaisesRegex(TypeError, 'invalid type'): + pool.SetFeatureSetDefaults('Some data') + + def testInvalidMessageType(self): + pool = descriptor_pool.DescriptorPool() + with self.assertRaisesRegex(TypeError, 'invalid type'): + pool.SetFeatureSetDefaults(descriptor_pb2.FileDescriptorProto()) + + def testInvalidEditionRange(self): + pool = descriptor_pool.DescriptorPool() + with self.assertRaisesRegex( + ValueError, 'Invalid edition range.*2023.*PROTO2' + ): + pool.SetFeatureSetDefaults( + descriptor_pb2.FeatureSetDefaults( + defaults=[ + descriptor_pb2.FeatureSetDefaults.FeatureSetEditionDefault( + edition=descriptor_pb2.Edition.EDITION_PROTO2, + features=unittest_features_pb2.DESCRIPTOR._GetFeatures(), + ) + ], + minimum_edition=descriptor_pb2.Edition.EDITION_2023, + maximum_edition=descriptor_pb2.Edition.EDITION_PROTO2, + ) + ) + file_desc = descriptor_pb2.FileDescriptorProto(name='some/file.proto') + file = pool.AddSerializedFile(file_desc.SerializeToString()) + + def testNotStrictlyIncreasing(self): + pool = descriptor_pool.DescriptorPool() + with self.assertRaisesRegex( + ValueError, 'not strictly increasing.*PROTO3.*greater.*PROTO2' + ): + pool.SetFeatureSetDefaults( + descriptor_pb2.FeatureSetDefaults( + defaults=[ + descriptor_pb2.FeatureSetDefaults.FeatureSetEditionDefault( + edition=descriptor_pb2.Edition.EDITION_PROTO3, + features=unittest_features_pb2.DESCRIPTOR._GetFeatures(), + ), + descriptor_pb2.FeatureSetDefaults.FeatureSetEditionDefault( + edition=descriptor_pb2.Edition.EDITION_PROTO2, + features=unittest_features_pb2.DESCRIPTOR._GetFeatures(), + ), + ], + minimum_edition=descriptor_pb2.Edition.EDITION_PROTO2, + maximum_edition=descriptor_pb2.Edition.EDITION_2023, + ) + ) + + def testUnknownEdition(self): + pool = descriptor_pool.DescriptorPool() + with self.assertRaisesRegex(ValueError, 'Invalid edition.*UNKNOWN'): + pool.SetFeatureSetDefaults( + descriptor_pb2.FeatureSetDefaults( + defaults=[ + descriptor_pb2.FeatureSetDefaults.FeatureSetEditionDefault( + edition=descriptor_pb2.Edition.EDITION_UNKNOWN, + features=unittest_features_pb2.DESCRIPTOR._GetFeatures(), + ), + descriptor_pb2.FeatureSetDefaults.FeatureSetEditionDefault( + edition=descriptor_pb2.Edition.EDITION_PROTO2, + features=unittest_features_pb2.DESCRIPTOR._GetFeatures(), + ), + ], + minimum_edition=descriptor_pb2.Edition.EDITION_PROTO2, + maximum_edition=descriptor_pb2.Edition.EDITION_2023, + ) + ) + + def testChangeAfterBuild(self): + pool = descriptor_pool.DescriptorPool() + file_desc = descriptor_pb2.FileDescriptorProto(name='some/file.proto') + file = pool.AddSerializedFile(file_desc.SerializeToString()) + file._GetFeatures() + defaults = descriptor_pb2.FeatureSetDefaults( + defaults=[ + descriptor_pb2.FeatureSetDefaults.FeatureSetEditionDefault( + edition=descriptor_pb2.Edition.EDITION_PROTO2, + features=unittest_features_pb2.DESCRIPTOR._GetFeatures(), + ) + ], + minimum_edition=descriptor_pb2.Edition.EDITION_PROTO2, + maximum_edition=descriptor_pb2.Edition.EDITION_2023, + ) + with self.assertRaisesRegex(ValueError, "defaults can't be changed"): + pool.SetFeatureSetDefaults(defaults) + + def testChangeDefaultPool(self): + defaults = descriptor_pb2.FeatureSetDefaults( + defaults=[ + descriptor_pb2.FeatureSetDefaults.FeatureSetEditionDefault( + edition=descriptor_pb2.Edition.EDITION_PROTO2, + features=unittest_features_pb2.DESCRIPTOR._GetFeatures(), + ) + ], + minimum_edition=descriptor_pb2.Edition.EDITION_PROTO2, + maximum_edition=descriptor_pb2.Edition.EDITION_2023, + ) + with self.assertRaisesRegex(ValueError, "defaults can't be changed"): + descriptor_pool.Default().SetFeatureSetDefaults(defaults) + + def testNoValidFeatures(self): + pool = descriptor_pool.DescriptorPool() + defaults = descriptor_pb2.FeatureSetDefaults( + defaults=[ + descriptor_pb2.FeatureSetDefaults.FeatureSetEditionDefault( + edition=descriptor_pb2.Edition.EDITION_2023, + features=unittest_features_pb2.DESCRIPTOR._GetFeatures(), + ) + ], + minimum_edition=descriptor_pb2.Edition.EDITION_PROTO2, + maximum_edition=descriptor_pb2.Edition.EDITION_2023, + ) + pool.SetFeatureSetDefaults(defaults) + file_desc = descriptor_pb2.FileDescriptorProto(name='some/file.proto') + with self.assertRaisesRegex(TypeError, 'No valid default found.*PROTO2'): + file = pool.AddSerializedFile(file_desc.SerializeToString()) + file._GetFeatures() + + def testBelowMinimum(self): + pool = descriptor_pool.DescriptorPool() + defaults = descriptor_pb2.FeatureSetDefaults( + defaults=[ + descriptor_pb2.FeatureSetDefaults.FeatureSetEditionDefault( + edition=descriptor_pb2.Edition.EDITION_PROTO3, + features=unittest_features_pb2.DESCRIPTOR._GetFeatures(), + ) + ], + minimum_edition=descriptor_pb2.Edition.EDITION_PROTO3, + maximum_edition=descriptor_pb2.Edition.EDITION_2023, + ) + pool.SetFeatureSetDefaults(defaults) + file_desc = descriptor_pb2.FileDescriptorProto(name='some/file.proto') + with self.assertRaisesRegex( + TypeError, 'PROTO2.*earlier than the minimum.*PROTO3' + ): + file = pool.AddSerializedFile(file_desc.SerializeToString()) + file._GetFeatures() + + def testAboveMaximum(self): + pool = descriptor_pool.DescriptorPool() + defaults = descriptor_pb2.FeatureSetDefaults( + defaults=[ + descriptor_pb2.FeatureSetDefaults.FeatureSetEditionDefault( + edition=descriptor_pb2.Edition.EDITION_PROTO2, + features=unittest_features_pb2.DESCRIPTOR._GetFeatures(), + ) + ], + minimum_edition=descriptor_pb2.Edition.EDITION_PROTO2, + maximum_edition=descriptor_pb2.Edition.EDITION_PROTO3, + ) + pool.SetFeatureSetDefaults(defaults) + file_desc = descriptor_pb2.FileDescriptorProto( + name='some/file.proto', + syntax='editions', + edition=descriptor_pb2.Edition.EDITION_2023, + ) + with self.assertRaisesRegex( + TypeError, '2023.*later than the maximum.*PROTO3' + ): + file = pool.AddSerializedFile(file_desc.SerializeToString()) + file._GetFeatures() + + TEST1_FILE = ProtoFile( 'google/protobuf/internal/descriptor_pool_test1.proto', 'google.protobuf.python.internal', diff --git a/python/google/protobuf/internal/descriptor_pool_test1.proto b/python/google/protobuf/internal/descriptor_pool_test1.proto index 8a7381188d..d254e82dbc 100644 --- a/python/google/protobuf/internal/descriptor_pool_test1.proto +++ b/python/google/protobuf/internal/descriptor_pool_test1.proto @@ -9,6 +9,17 @@ syntax = "proto2"; package google.protobuf.python.internal; +enum TopLevelEnumTest1 { + TOP_LEVEL_ENUM_TEST_1_NONE = 0; + TOP_LEVEL_ENUM_TEST_1_ONE = 1; +} + +extend DescriptorPoolTest1 { + optional TopLevelEnumTest1 top_level_extension_test1 = 1000; +} + +service DescriporPoolTestService {} + message DescriptorPoolTest1 { extensions 1000 to max; @@ -63,7 +74,7 @@ message DescriptorPoolTest2 { LAMBDA = 11; MU = 12; - reserved -1; + reserved - 1; reserved 536870913; // 0x20000001 } optional NestedEnum nested_enum = 1 [default = MU]; diff --git a/python/google/protobuf/internal/descriptor_test.py b/python/google/protobuf/internal/descriptor_test.py index 1adbad286e..bf833a4b8a 100755 --- a/python/google/protobuf/internal/descriptor_test.py +++ b/python/google/protobuf/internal/descriptor_test.py @@ -12,16 +12,22 @@ __author__ = 'robinson@google.com (Will Robinson)' import unittest import warnings -from google.protobuf import descriptor_pb2 -from google.protobuf.internal import api_implementation -from google.protobuf.internal import test_util from google.protobuf import descriptor +from google.protobuf import descriptor_pb2 from google.protobuf import descriptor_pool from google.protobuf import symbol_database from google.protobuf import text_format +from google.protobuf.internal import api_implementation +from google.protobuf.internal import legacy_features_pb2 +from google.protobuf.internal import test_util +from google.protobuf.internal import testing_refleaks + +from google.protobuf.internal import _parameterized from google.protobuf import unittest_custom_options_pb2 +from google.protobuf import unittest_features_pb2 from google.protobuf import unittest_import_pb2 from google.protobuf import unittest_pb2 +from google.protobuf import unittest_proto3_pb2 TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII = """ @@ -55,6 +61,7 @@ service DescriptorTestService { warnings.simplefilter('error', DeprecationWarning) +@testing_refleaks.TestCase class DescriptorTest(unittest.TestCase): def setUp(self): @@ -532,7 +539,9 @@ class DescriptorTest(unittest.TestCase): self.assertEqual(self.my_file.package, 'protobuf_unittest') self.assertEqual(self.my_file.pool, self.pool) self.assertFalse(self.my_file.has_options) - self.assertEqual(self.my_file.syntax, 'proto2') + self.assertEqual( + self.my_file.edition, descriptor_pb2.Edition.EDITION_PROTO2 + ) file_proto = descriptor_pb2.FileDescriptorProto() self.my_file.CopyToProto(file_proto) self.assertEqual(self.my_file.serialized_pb, @@ -1169,7 +1178,6 @@ class MakeDescriptorTest(unittest.TestCase): self.assertEqual(result.fields[0].cpp_type, descriptor.FieldDescriptor.CPPTYPE_UINT64) - def testMakeDescriptorWithOptions(self): descriptor_proto = descriptor_pb2.DescriptorProto() aggregate_message = unittest_custom_options_pb2.AggregateMessage @@ -1214,5 +1222,398 @@ class MakeDescriptorTest(unittest.TestCase): json_names[index]) +@testing_refleaks.TestCase +class FeaturesTest(_parameterized.TestCase): + + @_parameterized.named_parameters([ + ('File', lambda: descriptor_pb2.DESCRIPTOR), + ('Message', lambda: descriptor_pb2.FeatureSet.DESCRIPTOR), + ( + 'Enum', + lambda: descriptor_pb2.FeatureSet.FieldPresence.DESCRIPTOR, + ), + ( + 'Field', + lambda: descriptor_pb2.FeatureSet.DESCRIPTOR.fields_by_name[ + 'enum_type' + ], + ), + ]) + def testDescriptorProtoDefaultFeatures(self, desc): + self.assertEqual( + desc()._GetFeatures().field_presence, + descriptor_pb2.FeatureSet.FieldPresence.EXPLICIT, + ) + self.assertEqual( + desc()._GetFeatures().enum_type, + descriptor_pb2.FeatureSet.EnumType.CLOSED, + ) + self.assertEqual( + desc()._GetFeatures().repeated_field_encoding, + descriptor_pb2.FeatureSet.RepeatedFieldEncoding.EXPANDED, + ) + + def testDescriptorProtoOverrideFeatures(self): + desc = descriptor_pb2.SourceCodeInfo.Location.DESCRIPTOR.fields_by_name[ + 'path' + ] + self.assertEqual( + desc._GetFeatures().field_presence, + descriptor_pb2.FeatureSet.FieldPresence.EXPLICIT, + ) + self.assertEqual( + desc._GetFeatures().enum_type, + descriptor_pb2.FeatureSet.EnumType.CLOSED, + ) + self.assertEqual( + desc._GetFeatures().repeated_field_encoding, + descriptor_pb2.FeatureSet.RepeatedFieldEncoding.PACKED, + ) + + def testFeaturesStripped(self): + desc = legacy_features_pb2.TestEditionsMessage.DESCRIPTOR.fields_by_name[ + 'required_field' + ] + self.assertFalse(desc.GetOptions().HasField('features')) + + def testLegacyRequiredTransform(self): + desc = legacy_features_pb2.TestEditionsMessage.DESCRIPTOR + self.assertEqual( + desc.fields_by_name['required_field'].label, + descriptor.FieldDescriptor.LABEL_REQUIRED, + ) + + def testLegacyGroupTransform(self): + desc = legacy_features_pb2.TestEditionsMessage.DESCRIPTOR + self.assertEqual( + desc.fields_by_name['delimited_field'].type, + descriptor.FieldDescriptor.TYPE_GROUP, + ) + + def testLegacyInferRequired(self): + desc = unittest_pb2.TestRequired.DESCRIPTOR.fields_by_name['a'] + self.assertEqual( + desc._GetFeatures().field_presence, + descriptor_pb2.FeatureSet.FieldPresence.LEGACY_REQUIRED, + ) + + def testLegacyInferGroup(self): + desc = unittest_pb2.TestAllTypes.DESCRIPTOR.fields_by_name['optionalgroup'] + self.assertEqual( + desc._GetFeatures().message_encoding, + descriptor_pb2.FeatureSet.MessageEncoding.DELIMITED, + ) + + def testLegacyInferProto2Packed(self): + desc = unittest_pb2.TestPackedTypes.DESCRIPTOR.fields_by_name[ + 'packed_int32' + ] + self.assertEqual( + desc._GetFeatures().repeated_field_encoding, + descriptor_pb2.FeatureSet.RepeatedFieldEncoding.PACKED, + ) + + def testLegacyInferProto3Expanded(self): + desc = unittest_proto3_pb2.TestUnpackedTypes.DESCRIPTOR.fields_by_name[ + 'repeated_int32' + ] + self.assertEqual( + desc._GetFeatures().repeated_field_encoding, + descriptor_pb2.FeatureSet.RepeatedFieldEncoding.EXPANDED, + ) + + def testProto2Defaults(self): + features = unittest_pb2.TestAllTypes.DESCRIPTOR.fields_by_name[ + 'optional_int32' + ]._GetFeatures() + fs = descriptor_pb2.FeatureSet + self.assertEqual(features.field_presence, fs.FieldPresence.EXPLICIT) + self.assertEqual(features.enum_type, fs.EnumType.CLOSED) + self.assertEqual( + features.repeated_field_encoding, fs.RepeatedFieldEncoding.EXPANDED + ) + self.assertEqual(features.utf8_validation, fs.Utf8Validation.NONE) + self.assertEqual( + features.message_encoding, fs.MessageEncoding.LENGTH_PREFIXED + ) + self.assertEqual(features.json_format, fs.JsonFormat.LEGACY_BEST_EFFORT) + + def testProto3Defaults(self): + features = unittest_proto3_pb2.TestAllTypes.DESCRIPTOR.fields_by_name[ + 'optional_int32' + ]._GetFeatures() + fs = descriptor_pb2.FeatureSet + self.assertEqual(features.field_presence, fs.FieldPresence.IMPLICIT) + self.assertEqual(features.enum_type, fs.EnumType.OPEN) + self.assertEqual( + features.repeated_field_encoding, fs.RepeatedFieldEncoding.PACKED + ) + self.assertEqual(features.utf8_validation, fs.Utf8Validation.VERIFY) + self.assertEqual( + features.message_encoding, fs.MessageEncoding.LENGTH_PREFIXED + ) + self.assertEqual(features.json_format, fs.JsonFormat.ALLOW) + + +def GetTestFeature(desc): + return ( + desc._GetFeatures() + .Extensions[unittest_features_pb2.test] + .int_multiple_feature + ) + + +def SetTestFeature(proto, value): + proto.options.features.Extensions[ + unittest_features_pb2.test + ].int_multiple_feature = value + + +@testing_refleaks.TestCase +class FeatureInheritanceTest(unittest.TestCase): + + def setUp(self): + super(FeatureInheritanceTest, self).setUp() + self.file_proto = descriptor_pb2.FileDescriptorProto( + name='some/filename/some.proto', + package='protobuf_unittest', + edition=descriptor_pb2.Edition.EDITION_2023, + syntax='editions', + ) + self.top_extension_proto = self.file_proto.extension.add( + name='top_extension', + number=10, + type=descriptor_pb2.FieldDescriptorProto.TYPE_INT32, + label=descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL, + extendee='.protobuf_unittest.TopMessage', + ) + self.top_enum_proto = self.file_proto.enum_type.add(name='TopEnum') + self.enum_value_proto = self.top_enum_proto.value.add( + name='TOP_VALUE', number=0 + ) + self.top_message_proto = self.file_proto.message_type.add(name='TopMessage') + self.field_proto = self.top_message_proto.field.add( + name='field', + number=1, + type=descriptor_pb2.FieldDescriptorProto.TYPE_INT32, + label=descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL, + ) + self.top_message_proto.extension_range.add(start=10, end=20) + self.nested_extension_proto = self.top_message_proto.extension.add( + name='nested_extension', + number=11, + type=descriptor_pb2.FieldDescriptorProto.TYPE_INT32, + label=descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL, + extendee='.protobuf_unittest.TopMessage', + ) + self.nested_message_proto = self.top_message_proto.nested_type.add( + name='NestedMessage' + ) + self.nested_enum_proto = self.top_message_proto.enum_type.add( + name='NestedEnum' + ) + self.nested_enum_proto.value.add(name='NESTED_VALUE', number=0) + self.oneof_proto = self.top_message_proto.oneof_decl.add(name='Oneof') + self.oneof_field_proto = self.top_message_proto.field.add( + name='oneof_field', + number=2, + type=descriptor_pb2.FieldDescriptorProto.TYPE_INT32, + label=descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL, + oneof_index=0, + ) + + self.service_proto = self.file_proto.service.add(name='TestService') + self.method_proto = self.service_proto.method.add( + name='CallMethod', + input_type='.protobuf_unittest.TopMessage', + output_type='.protobuf_unittest.TopMessage', + ) + + def BuildPool(self): + + # These can't be put onto the fixture without breaking the refleak checks. + class ReturnObject: + pass + + ret = ReturnObject() + ret.pool = descriptor_pool.DescriptorPool() + defaults = descriptor_pb2.FeatureSetDefaults( + defaults=[ + descriptor_pb2.FeatureSetDefaults.FeatureSetEditionDefault( + edition=descriptor_pb2.Edition.EDITION_PROTO2, + features=unittest_pb2.TestAllTypes.DESCRIPTOR._GetFeatures(), + ) + ], + minimum_edition=descriptor_pb2.Edition.EDITION_PROTO2, + maximum_edition=descriptor_pb2.Edition.EDITION_2023, + ) + defaults.defaults[0].features.Extensions[ + unittest_features_pb2.test + ].int_multiple_feature = 1 + ret.pool.SetFeatureSetDefaults(defaults) + + ret.file = ret.pool.AddSerializedFile(self.file_proto.SerializeToString()) + ret.top_message = ret.pool.FindMessageTypeByName( + 'protobuf_unittest.TopMessage' + ) + ret.top_enum = ret.pool.FindEnumTypeByName('protobuf_unittest.TopEnum') + ret.top_extension = ret.pool.FindExtensionByName( + 'protobuf_unittest.top_extension' + ) + ret.nested_message = ret.top_message.nested_types_by_name['NestedMessage'] + ret.nested_enum = ret.top_message.enum_types_by_name['NestedEnum'] + ret.nested_extension = ret.top_message.extensions_by_name[ + 'nested_extension' + ] + ret.field = ret.top_message.fields_by_name['field'] + ret.oneof = ret.top_message.oneofs_by_name['Oneof'] + ret.oneof_field = ret.top_message.fields_by_name['oneof_field'] + ret.enum_value = ret.top_enum.values_by_name['TOP_VALUE'] + ret.service = ret.pool.FindServiceByName('protobuf_unittest.TestService') + ret.method = ret.service.methods_by_name['CallMethod'] + return ret + + def testFileDefaults(self): + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.file), 1) + + def testFileOverride(self): + SetTestFeature(self.file_proto, 3) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.file), 3) + + def testFileMessageInherit(self): + SetTestFeature(self.file_proto, 3) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.top_message), 3) + + def testFileMessageOverride(self): + SetTestFeature(self.file_proto, 3) + SetTestFeature(self.top_message_proto, 5) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.top_message), 5) + + def testFileEnumInherit(self): + SetTestFeature(self.file_proto, 3) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.top_enum), 3) + + def testFileEnumOverride(self): + SetTestFeature(self.file_proto, 3) + SetTestFeature(self.top_enum_proto, 5) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.top_enum), 5) + + def testFileExtensionInherit(self): + SetTestFeature(self.file_proto, 3) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.top_extension), 3) + + def testFileExtensionOverride(self): + SetTestFeature(self.file_proto, 3) + SetTestFeature(self.top_extension_proto, 5) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.top_extension), 5) + + def testFileServiceInherit(self): + SetTestFeature(self.file_proto, 3) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.service), 3) + + def testFileServiceOverride(self): + SetTestFeature(self.file_proto, 3) + SetTestFeature(self.service_proto, 5) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.service), 5) + + def testMessageFieldInherit(self): + SetTestFeature(self.top_message_proto, 3) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.field), 3) + + def testMessageFieldOverride(self): + SetTestFeature(self.top_message_proto, 3) + SetTestFeature(self.field_proto, 5) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.field), 5) + + def testMessageEnumInherit(self): + SetTestFeature(self.top_message_proto, 3) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.nested_enum), 3) + + def testMessageEnumOverride(self): + SetTestFeature(self.top_message_proto, 3) + SetTestFeature(self.nested_enum_proto, 5) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.nested_enum), 5) + + def testMessageMessageInherit(self): + SetTestFeature(self.top_message_proto, 3) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.nested_message), 3) + + def testMessageMessageOverride(self): + SetTestFeature(self.top_message_proto, 3) + SetTestFeature(self.nested_message_proto, 5) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.nested_message), 5) + + def testMessageExtensionInherit(self): + SetTestFeature(self.top_message_proto, 3) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.nested_extension), 3) + + def testMessageExtensionOverride(self): + SetTestFeature(self.top_message_proto, 3) + SetTestFeature(self.nested_extension_proto, 5) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.nested_extension), 5) + + def testMessageOneofInherit(self): + SetTestFeature(self.top_message_proto, 3) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.oneof), 3) + + def testMessageOneofOverride(self): + SetTestFeature(self.top_message_proto, 3) + SetTestFeature(self.oneof_proto, 5) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.oneof), 5) + + def testOneofFieldInherit(self): + SetTestFeature(self.oneof_proto, 3) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.oneof_field), 3) + + def testOneofFieldOverride(self): + SetTestFeature(self.oneof_proto, 3) + SetTestFeature(self.oneof_field_proto, 5) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.oneof_field), 5) + + def testEnumValueInherit(self): + SetTestFeature(self.top_enum_proto, 3) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.enum_value), 3) + + def testEnumValueOverride(self): + SetTestFeature(self.top_enum_proto, 3) + SetTestFeature(self.enum_value_proto, 5) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.enum_value), 5) + + def testServiceMethodInherit(self): + SetTestFeature(self.service_proto, 3) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.method), 3) + + def testServiceMethodOverride(self): + SetTestFeature(self.service_proto, 3) + SetTestFeature(self.method_proto, 5) + pool = self.BuildPool() + self.assertEqual(GetTestFeature(pool.method), 5) + + if __name__ == '__main__': unittest.main() diff --git a/python/google/protobuf/internal/legacy_features.proto b/python/google/protobuf/internal/legacy_features.proto new file mode 100644 index 0000000000..ef803ddbad --- /dev/null +++ b/python/google/protobuf/internal/legacy_features.proto @@ -0,0 +1,18 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// Test that features with legacy descriptor helpers get properly converted. + +edition = "2023"; + +package google.protobuf.internal; + +message TestEditionsMessage { + int32 required_field = 1 [features.field_presence = LEGACY_REQUIRED]; + TestEditionsMessage delimited_field = 2 + [features.message_encoding = DELIMITED]; +} diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py index 0bac00da02..a6223c2a7e 100755 --- a/python/google/protobuf/internal/message_test.py +++ b/python/google/protobuf/internal/message_test.py @@ -48,7 +48,6 @@ UCS2_MAXUNICODE = 65535 warnings.simplefilter('error', DeprecationWarning) - @_parameterized.named_parameters(('_proto2', unittest_pb2), ('_proto3', unittest_proto3_arena_pb2)) @testing_refleaks.TestCase @@ -1341,6 +1340,17 @@ class Proto2Test(unittest.TestCase): self.assertEqual(False, message.optional_bool) self.assertEqual(0, message.optional_nested_message.bb) + def testDel(self): + msg = unittest_pb2.TestAllTypes() + + # Fields cannot be deleted. + with self.assertRaises(AttributeError): + del msg.optional_int32 + with self.assertRaises(AttributeError): + del msg.optional_bool + with self.assertRaises(AttributeError): + del msg.repeated_nested_message + def testAssignInvalidEnum(self): """Assigning an invalid enum number is not allowed in proto2.""" m = unittest_pb2.TestAllTypes() diff --git a/python/google/protobuf/internal/python_edition_defaults.py.template b/python/google/protobuf/internal/python_edition_defaults.py.template new file mode 100644 index 0000000000..56bdf042e6 --- /dev/null +++ b/python/google/protobuf/internal/python_edition_defaults.py.template @@ -0,0 +1,5 @@ +""" +This file contains the serialized FeatureSetDefaults object corresponding to +the Pure Python runtime. This is used for feature resolution under Editions. +""" +_PROTOBUF_INTERNAL_PYTHON_EDITION_DEFAULTS = b"DEFAULTS_VALUE" diff --git a/python/google/protobuf/internal/python_message.py b/python/google/protobuf/internal/python_message.py index 40c7764534..870ff185f0 100755 --- a/python/google/protobuf/internal/python_message.py +++ b/python/google/protobuf/internal/python_message.py @@ -1385,15 +1385,9 @@ def _Clear(self): def _UnknownFields(self): - warnings.warn( - 'message.UnknownFields() is deprecated. Please use the add one ' - 'feature unknown_fields.UnknownFieldSet(message) in ' - 'unknown_fields.py instead.' - ) - if self._unknown_field_set is None: # pylint: disable=protected-access - # pylint: disable=protected-access - self._unknown_field_set = containers.UnknownFieldSet() - return self._unknown_field_set # pylint: disable=protected-access + raise NotImplementedError('Please use the add-on feaure ' + 'unknown_fields.UnknownFieldSet(message) in ' + 'unknown_fields.py instead.') def _DiscardUnknownFields(self): diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py index 2230d0c94d..1f22b86458 100755 --- a/python/google/protobuf/internal/reflection_test.py +++ b/python/google/protobuf/internal/reflection_test.py @@ -1462,6 +1462,7 @@ class Proto2ReflectionTest(unittest.TestCase): if api_implementation.Type() != 'python': return + file = descriptor.FileDescriptor(name='foo.proto', package='') FieldDescriptor = descriptor.FieldDescriptor foo_field_descriptor = FieldDescriptor( name='foo_field', full_name='MyProto.foo_field', @@ -1470,7 +1471,7 @@ class Proto2ReflectionTest(unittest.TestCase): label=FieldDescriptor.LABEL_OPTIONAL, default_value=0, containing_type=None, message_type=None, enum_type=None, is_extension=False, extension_scope=None, - options=descriptor_pb2.FieldOptions(), + options=descriptor_pb2.FieldOptions(), file=file, # pylint: disable=protected-access create_key=descriptor._internal_create_key) mydescriptor = descriptor.Descriptor( @@ -1478,6 +1479,7 @@ class Proto2ReflectionTest(unittest.TestCase): containing_type=None, nested_types=[], enum_types=[], fields=[foo_field_descriptor], extensions=[], options=descriptor_pb2.MessageOptions(), + file=file, # pylint: disable=protected-access create_key=descriptor._internal_create_key) diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc index 44d9e45177..2c5bd1a0fe 100644 --- a/python/google/protobuf/pyext/descriptor.cc +++ b/python/google/protobuf/pyext/descriptor.cc @@ -9,9 +9,6 @@ #include "google/protobuf/pyext/descriptor.h" -#include "absl/log/absl_check.h" -#include "google/protobuf/descriptor_legacy.h" - #define PY_SSIZE_T_CLEAN #include #include @@ -21,14 +18,17 @@ #include #include "google/protobuf/descriptor.pb.h" +#include "absl/container/flat_hash_map.h" +#include "absl/log/absl_check.h" +#include "absl/strings/string_view.h" +#include "google/protobuf/descriptor.h" #include "google/protobuf/dynamic_message.h" +#include "google/protobuf/io/coded_stream.h" #include "google/protobuf/pyext/descriptor_containers.h" #include "google/protobuf/pyext/descriptor_pool.h" #include "google/protobuf/pyext/message.h" #include "google/protobuf/pyext/message_factory.h" #include "google/protobuf/pyext/scoped_pyobject_ptr.h" -#include "absl/strings/string_view.h" -#include "google/protobuf/io/coded_stream.h" #define PyString_AsStringAndSize(ob, charpp, sizep) \ (PyUnicode_Check(ob) \ @@ -230,28 +230,25 @@ bool Reparse( } return true; } -// Converts options into a Python protobuf, and cache the result. + +// Converts descriptor messages into a Python protobuf, and cache the result. // // This is a bit tricky because options can contain extension fields defined in // the same proto file. In this case the options parsed from the serialized_pb // have unknown fields, and we need to parse them again. // // Always returns a new reference. -template -static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) { - // Options are cached in the pool that owns the descriptor. +static PyObject* GetOrBuildMessageInDefaultPool( + absl::flat_hash_map& cache, const void* key, + const Message& message) { // First search in the cache. - PyDescriptorPool* caching_pool = GetDescriptorPool_FromPool( - GetFileDescriptor(descriptor)->pool()); - std::unordered_map* descriptor_options = - caching_pool->descriptor_options; - if (descriptor_options->find(descriptor) != descriptor_options->end()) { - PyObject *value = (*descriptor_options)[descriptor]; + if (cache.find(key) != cache.end()) { + PyObject* value = cache[key]; Py_INCREF(value); return value; } - // Similar to the C++ implementation, we return an Options object from the + // Similar to the C++ implementation, we return a message object from the // default (generated) factory, so that client code know that they can use // extensions from generated files: // d.GetOptions().Extensions[some_pb2.extension] @@ -262,14 +259,13 @@ static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) { PyMessageFactory* message_factory = GetDefaultDescriptorPool()->py_message_factory; - // Build the Options object: get its Python class, and make a copy of the C++ + // Build the message object: get its Python class, and make a copy of the C++ // read-only instance. - const Message& options(descriptor->options()); - const Descriptor *message_type = options.GetDescriptor(); - CMessageClass* message_class = message_factory::GetOrCreateMessageClass( - message_factory, message_type); + const Descriptor* message_type = message.GetDescriptor(); + CMessageClass* message_class = + message_factory::GetOrCreateMessageClass(message_factory, message_type); if (message_class == nullptr) { - PyErr_Format(PyExc_TypeError, "Could not retrieve class for Options: %s", + PyErr_Format(PyExc_TypeError, "Could not retrieve class for: %s", message_type->full_name().c_str()); return nullptr; } @@ -281,20 +277,20 @@ static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) { return nullptr; } if (!PyObject_TypeCheck(value.get(), CMessage_Type)) { - PyErr_Format(PyExc_TypeError, "Invalid class for %s: %s", - message_type->full_name().c_str(), - Py_TYPE(value.get())->tp_name); - return nullptr; + PyErr_Format(PyExc_TypeError, "Invalid class for %s: %s", + message_type->full_name().c_str(), + Py_TYPE(value.get())->tp_name); + return nullptr; } CMessage* cmsg = reinterpret_cast(value.get()); - const Reflection* reflection = options.GetReflection(); - const UnknownFieldSet& unknown_fields(reflection->GetUnknownFields(options)); + const Reflection* reflection = message.GetReflection(); + const UnknownFieldSet& unknown_fields(reflection->GetUnknownFields(message)); if (unknown_fields.empty()) { - cmsg->message->CopyFrom(options); + cmsg->message->CopyFrom(message); } else { // Reparse options string! XXX call cmessage::MergeFromString - if (!Reparse(message_factory, options, cmsg->message)) { + if (!Reparse(message_factory, message, cmsg->message)) { PyErr_Format(PyExc_ValueError, "Error reparsing Options message"); return nullptr; } @@ -302,11 +298,35 @@ static PyObject* GetOrBuildOptions(const DescriptorClass *descriptor) { // Cache the result. Py_INCREF(value.get()); - (*descriptor_options)[descriptor] = value.get(); + cache[key] = value.get(); return value.release(); } +template +static PyObject* GetOrBuildOptions(const DescriptorClass* descriptor) { + // Options are cached in the pool that owns the descriptor. + PyDescriptorPool* caching_pool = + GetDescriptorPool_FromPool(GetFileDescriptor(descriptor)->pool()); + return GetOrBuildMessageInDefaultPool(*caching_pool->descriptor_options, + descriptor, descriptor->options()); +} + +template +static PyObject* GetFeaturesImpl(const DescriptorClass* descriptor) { + if (descriptor == nullptr) { + return nullptr; + } + const FeatureSet& features = + internal::InternalFeatureHelper::GetFeatures(*descriptor); + + // Features are cached in the pool that owns the descriptor. + PyDescriptorPool* caching_pool = + GetDescriptorPool_FromPool(GetFileDescriptor(descriptor)->pool()); + return GetOrBuildMessageInDefaultPool(*caching_pool->descriptor_features, + descriptor, features); +} + // Copy the C++ descriptor to a Python message. // The Python message is an instance of descriptor_pb2.DescriptorProto // or similar. @@ -638,6 +658,10 @@ static PyObject* GetOptions(PyBaseDescriptor *self) { return GetOrBuildOptions(_GetDescriptor(self)); } +static PyObject* GetFeatures(PyBaseDescriptor* self) { + return GetFeaturesImpl(_GetDescriptor(self)); +} + static int SetOptions(PyBaseDescriptor *self, PyObject *value, void *closure) { return CheckCalledFromGeneratedFile("_options"); @@ -671,12 +695,6 @@ static PyObject* EnumValueName(PyBaseDescriptor *self, PyObject *args) { return PyString_FromCppString(enum_value->name()); } -static PyObject* GetSyntax(PyBaseDescriptor *self, void *closure) { - std::string syntax(FileDescriptorLegacy::SyntaxName( - FileDescriptorLegacy(_GetDescriptor(self)->file()).syntax())); - return PyUnicode_InternFromString(syntax.c_str()); -} - static PyGetSetDef Getters[] = { {"name", (getter)GetName, nullptr, "Last name"}, {"full_name", (getter)GetFullName, nullptr, "Full name"}, @@ -713,12 +731,12 @@ static PyGetSetDef Getters[] = { {"_options", (getter) nullptr, (setter)SetOptions, "Options"}, {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions, "Serialized Options"}, - {"syntax", (getter)GetSyntax, (setter) nullptr, "Syntax"}, {nullptr}, }; static PyMethodDef Methods[] = { {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"_GetFeatures", (PyCFunction)GetFeatures, METH_NOARGS}, {"CopyToProto", (PyCFunction)CopyToProto, METH_O}, {"EnumValueName", (PyCFunction)EnumValueName, METH_VARARGS}, {nullptr}, @@ -1004,6 +1022,10 @@ static PyObject* GetOptions(PyBaseDescriptor *self) { return GetOrBuildOptions(_GetDescriptor(self)); } +static PyObject* GetFeatures(PyBaseDescriptor* self) { + return GetFeaturesImpl(_GetDescriptor(self)); +} + static int SetOptions(PyBaseDescriptor *self, PyObject *value, void *closure) { return CheckCalledFromGeneratedFile("_options"); @@ -1051,6 +1073,7 @@ static PyGetSetDef Getters[] = { static PyMethodDef Methods[] = { {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"_GetFeatures", (PyCFunction)GetFeatures, METH_NOARGS}, {nullptr}, }; @@ -1179,6 +1202,10 @@ static PyObject* GetOptions(PyBaseDescriptor *self) { return GetOrBuildOptions(_GetDescriptor(self)); } +static PyObject* GetFeatures(PyBaseDescriptor* self) { + return GetFeaturesImpl(_GetDescriptor(self)); +} + static int SetOptions(PyBaseDescriptor *self, PyObject *value, void *closure) { return CheckCalledFromGeneratedFile("_options"); @@ -1195,6 +1222,7 @@ static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { static PyMethodDef Methods[] = { {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"_GetFeatures", (PyCFunction)GetFeatures, METH_NOARGS}, {"CopyToProto", (PyCFunction)CopyToProto, METH_O}, {nullptr}, }; @@ -1316,6 +1344,10 @@ static PyObject* GetOptions(PyBaseDescriptor *self) { return GetOrBuildOptions(_GetDescriptor(self)); } +static PyObject* GetFeatures(PyBaseDescriptor* self) { + return GetFeaturesImpl(_GetDescriptor(self)); +} + static int SetOptions(PyBaseDescriptor *self, PyObject *value, void *closure) { return CheckCalledFromGeneratedFile("_options"); @@ -1342,6 +1374,7 @@ static PyGetSetDef Getters[] = { static PyMethodDef Methods[] = { {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"_GetFeatures", (PyCFunction)GetFeatures, METH_NOARGS}, {nullptr}, }; @@ -1482,6 +1515,10 @@ static PyObject* GetOptions(PyFileDescriptor *self) { return GetOrBuildOptions(_GetDescriptor(self)); } +static PyObject* GetFeatures(PyFileDescriptor* self) { + return GetFeaturesImpl(_GetDescriptor(self)); +} + static int SetOptions(PyFileDescriptor *self, PyObject *value, void *closure) { return CheckCalledFromGeneratedFile("_options"); @@ -1492,10 +1529,8 @@ static int SetSerializedOptions(PyFileDescriptor *self, PyObject *value, return CheckCalledFromGeneratedFile("_serialized_options"); } -static PyObject* GetSyntax(PyFileDescriptor *self, void *closure) { - std::string syntax(FileDescriptorLegacy::SyntaxName( - FileDescriptorLegacy(_GetDescriptor(self)).syntax())); - return PyUnicode_InternFromString(syntax.c_str()); +static PyObject* GetEdition(PyFileDescriptor* self, void* closure) { + return PyLong_FromLong(_GetDescriptor(self)->edition()); } static PyObject* CopyToProto(PyFileDescriptor *self, PyObject *target) { @@ -1524,13 +1559,14 @@ static PyGetSetDef Getters[] = { {"_options", (getter) nullptr, (setter)SetOptions, "Options"}, {"_serialized_options", (getter) nullptr, (setter)SetSerializedOptions, "Serialized Options"}, - {"syntax", (getter)GetSyntax, (setter) nullptr, "Syntax"}, + {"edition", (getter)GetEdition, (setter) nullptr, "Edition"}, {nullptr}, }; static PyMethodDef Methods[] = { {"GetDebugString", (PyCFunction)GetDebugString, METH_NOARGS}, {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"_GetFeatures", (PyCFunction)GetFeatures, METH_NOARGS}, {"CopyToProto", (PyCFunction)CopyToProto, METH_O}, {nullptr}, }; @@ -1670,6 +1706,10 @@ static PyObject* GetOptions(PyBaseDescriptor *self) { return GetOrBuildOptions(_GetDescriptor(self)); } +static PyObject* GetFeatures(PyBaseDescriptor* self) { + return GetFeaturesImpl(_GetDescriptor(self)); +} + static int SetOptions(PyBaseDescriptor *self, PyObject *value, void *closure) { return CheckCalledFromGeneratedFile("_options"); @@ -1697,6 +1737,7 @@ static PyGetSetDef Getters[] = { static PyMethodDef Methods[] = { {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"_GetFeatures", (PyCFunction)GetFeatures, METH_NOARGS}, {nullptr}, }; @@ -1800,6 +1841,10 @@ static PyObject* GetOptions(PyBaseDescriptor *self) { return GetOrBuildOptions(_GetDescriptor(self)); } +static PyObject* GetFeatures(PyBaseDescriptor* self) { + return GetFeaturesImpl(_GetDescriptor(self)); +} + static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { return CopyToPythonProto(_GetDescriptor(self), target); @@ -1818,6 +1863,7 @@ static PyGetSetDef Getters[] = { static PyMethodDef Methods[] = { {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"_GetFeatures", (PyCFunction)GetFeatures, METH_NOARGS}, {"CopyToProto", (PyCFunction)CopyToProto, METH_O}, {"FindMethodByName", (PyCFunction)FindMethodByName, METH_O}, {nullptr}, @@ -1926,6 +1972,10 @@ static PyObject* GetOptions(PyBaseDescriptor *self) { return GetOrBuildOptions(_GetDescriptor(self)); } +static PyObject* GetFeatures(PyBaseDescriptor* self) { + return GetFeaturesImpl(_GetDescriptor(self)); +} + static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) { return CopyToPythonProto(_GetDescriptor(self), target); } @@ -1947,6 +1997,7 @@ static PyGetSetDef Getters[] = { static PyMethodDef Methods[] = { {"GetOptions", (PyCFunction)GetOptions, METH_NOARGS}, + {"_GetFeatures", (PyCFunction)GetFeatures, METH_NOARGS}, {"CopyToProto", (PyCFunction)CopyToProto, METH_O}, {nullptr}, }; diff --git a/python/google/protobuf/pyext/descriptor_database.cc b/python/google/protobuf/pyext/descriptor_database.cc index 92d1928493..2a608e5339 100644 --- a/python/google/protobuf/pyext/descriptor_database.cc +++ b/python/google/protobuf/pyext/descriptor_database.cc @@ -16,6 +16,7 @@ #include "google/protobuf/descriptor.pb.h" #include "absl/log/absl_log.h" +#include "google/protobuf/message.h" #include "google/protobuf/pyext/message.h" #include "google/protobuf/pyext/scoped_pyobject_ptr.h" @@ -54,7 +55,7 @@ static bool GetFileDescriptorProto(PyObject* py_descriptor, message->message->GetDescriptor() == filedescriptor_descriptor) { // Fast path: Just use the pointer. FileDescriptorProto* file_proto = - static_cast(message->message); + google::protobuf::DownCastToGenerated(message->message); *output = *file_proto; return true; } else { diff --git a/python/google/protobuf/pyext/descriptor_pool.cc b/python/google/protobuf/pyext/descriptor_pool.cc index 6ba3c60bdf..272dcb852e 100644 --- a/python/google/protobuf/pyext/descriptor_pool.cc +++ b/python/google/protobuf/pyext/descriptor_pool.cc @@ -16,6 +16,8 @@ #include #include "google/protobuf/descriptor.pb.h" +#include "absl/container/flat_hash_map.h" +#include "absl/status/status.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_replace.h" #include "absl/strings/string_view.h" @@ -95,7 +97,9 @@ static PyDescriptorPool* _CreateDescriptorPool() { cpool->is_owned = false; cpool->is_mutable = false; - cpool->descriptor_options = new std::unordered_map(); + cpool->descriptor_options = new absl::flat_hash_map(); + cpool->descriptor_features = + new absl::flat_hash_map(); cpool->py_message_factory = message_factory::NewMessageFactory( &PyMessageFactory_Type, cpool); @@ -191,12 +195,16 @@ static void Dealloc(PyObject* pself) { PyDescriptorPool* self = reinterpret_cast(pself); descriptor_pool_map->erase(self->pool); Py_CLEAR(self->py_message_factory); - for (std::unordered_map::iterator it = - self->descriptor_options->begin(); + for (auto it = self->descriptor_options->begin(); it != self->descriptor_options->end(); ++it) { Py_DECREF(it->second); } delete self->descriptor_options; + for (auto it = self->descriptor_features->begin(); + it != self->descriptor_features->end(); ++it) { + Py_DECREF(it->second); + } + delete self->descriptor_features; delete self->database; if (self->is_owned) { delete self->pool; @@ -635,11 +643,51 @@ static PyObject* Add(PyObject* self, PyObject* file_descriptor_proto) { return AddSerializedFile(self, serialized_pb.get()); } +static PyObject* SetFeatureSetDefaults(PyObject* pself, PyObject* pdefaults) { + PyDescriptorPool* self = reinterpret_cast(pself); + + if (!self->is_mutable) { + PyErr_SetString( + PyExc_RuntimeError, + "This DescriptorPool is not mutable and cannot add new definitions."); + return nullptr; + } + + if (!PyObject_TypeCheck(pdefaults, CMessage_Type)) { + PyErr_Format(PyExc_TypeError, + "SetFeatureSetDefaults called with invalid type: got %s.", + Py_TYPE(pdefaults)->tp_name); + return nullptr; + } + + CMessage* defaults = reinterpret_cast(pdefaults); + if (defaults->message->GetDescriptor() != + FeatureSetDefaults::GetDescriptor()) { + PyErr_Format(PyExc_TypeError, + "SetFeatureSetDefaults called with invalid type: " + " got %s.", + defaults->message->GetDescriptor()->full_name().c_str()); + return nullptr; + } + + absl::Status status = + const_cast(self->pool) + ->SetFeatureSetDefaults( + *reinterpret_cast(defaults->message)); + if (!status.ok()) { + PyErr_SetString(PyExc_ValueError, std::string(status.message()).c_str()); + return nullptr; + } + Py_RETURN_NONE; +} + static PyMethodDef Methods[] = { {"Add", Add, METH_O, "Adds the FileDescriptorProto and its types to this pool."}, {"AddSerializedFile", AddSerializedFile, METH_O, "Adds a serialized FileDescriptorProto to this pool."}, + {"SetFeatureSetDefaults", SetFeatureSetDefaults, METH_O, + "Sets the default feature mappings used during the build."}, {"AddFileDescriptor", AddFileDescriptor, METH_O, "No-op. Add() must have been called before."}, diff --git a/python/google/protobuf/pyext/descriptor_pool.h b/python/google/protobuf/pyext/descriptor_pool.h index 2814cc21c8..b2ce55ce51 100644 --- a/python/google/protobuf/pyext/descriptor_pool.h +++ b/python/google/protobuf/pyext/descriptor_pool.h @@ -11,7 +11,7 @@ #define PY_SSIZE_T_CLEAN #include -#include +#include "absl/container/flat_hash_map.h" #include "google/protobuf/descriptor.h" namespace google { @@ -65,7 +65,9 @@ typedef struct PyDescriptorPool { // Cache the options for any kind of descriptor. // Descriptor pointers are owned by the DescriptorPool above. // Python objects are owned by the map. - std::unordered_map* descriptor_options; + absl::flat_hash_map* descriptor_options; + // Similar cache for features. + absl::flat_hash_map* descriptor_features; } PyDescriptorPool; diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc index 449a11d997..7e01f64ae8 100644 --- a/python/google/protobuf/pyext/message.cc +++ b/python/google/protobuf/pyext/message.cc @@ -2346,16 +2346,11 @@ static PyObject* GetExtensionDict(CMessage* self, void *closure) { } static PyObject* GetUnknownFields(CMessage* self) { - PyErr_Warn(nullptr, - "message.UnknownFields() is deprecated. Please use the " - "add one feature unknown_fields.UnknownFieldSet(message) in " - "unknown_fields.py instead."); - if (self->unknown_field_set == nullptr) { - self->unknown_field_set = unknown_fields::NewPyUnknownFields(self); - } else { - Py_INCREF(self->unknown_field_set); - } - return self->unknown_field_set; + PyErr_Format(PyExc_NotImplementedError, + "Please use the add-on feature " + "unknown_fields.UnknownFieldSet(message) in " + "unknown_fields.py instead."); + return nullptr; } static PyGetSetDef Getters[] = { diff --git a/python/map.c b/python/map.c index a1d75de9a1..c4cd95eb7d 100644 --- a/python/map.c +++ b/python/map.c @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "python/map.h" @@ -179,7 +156,7 @@ int PyUpb_MapContainer_AssignSubscript(PyObject* _self, PyObject* key, const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1); upb_Arena* arena = PyUpb_Arena_Get(self->arena); upb_MessageValue u_key, u_val; - if (!PyUpb_PyToUpb(key, key_f, &u_key, arena)) return -1; + if (!PyUpb_PyToUpb(key, key_f, &u_key, NULL)) return -1; if (val) { if (!PyUpb_PyToUpb(val, val_f, &u_val, arena)) return -1; @@ -200,9 +177,8 @@ PyObject* PyUpb_MapContainer_Subscript(PyObject* _self, PyObject* key) { const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f); const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0); const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1); - upb_Arena* arena = PyUpb_Arena_Get(self->arena); upb_MessageValue u_key, u_val; - if (!PyUpb_PyToUpb(key, key_f, &u_key, arena)) return NULL; + if (!PyUpb_PyToUpb(key, key_f, &u_key, NULL)) return NULL; if (!map || !upb_Map_Get(map, u_key, &u_val)) { map = PyUpb_MapContainer_EnsureReified(_self); upb_Arena* arena = PyUpb_Arena_Get(self->arena); @@ -256,9 +232,8 @@ static PyObject* PyUpb_MapContainer_Get(PyObject* _self, PyObject* args, const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(f); const upb_FieldDef* key_f = upb_MessageDef_Field(entry_m, 0); const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1); - upb_Arena* arena = PyUpb_Arena_Get(self->arena); upb_MessageValue u_key, u_val; - if (!PyUpb_PyToUpb(key, key_f, &u_key, arena)) return NULL; + if (!PyUpb_PyToUpb(key, key_f, &u_key, NULL)) return NULL; if (map && upb_Map_Get(map, u_key, &u_val)) { return PyUpb_UpbToPy(u_val, val_f, self->arena); } diff --git a/python/map.h b/python/map.h index 6c2c47d4d4..7c982fff77 100644 --- a/python/map.h +++ b/python/map.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef PYUPB_MAP_H__ #define PYUPB_MAP_H__ diff --git a/python/message.c b/python/message.c index 0777e7ed5f..2cca1c1f0f 100644 --- a/python/message.c +++ b/python/message.c @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "python/message.h" @@ -1028,6 +1005,12 @@ __attribute__((flatten)) static PyObject* PyUpb_Message_GetAttr( static int PyUpb_Message_SetAttr(PyObject* _self, PyObject* attr, PyObject* value) { PyUpb_Message* self = (void*)_self; + + if (value == NULL) { + PyErr_SetString(PyExc_AttributeError, "Cannot delete field attribute"); + return -1; + } + const upb_FieldDef* field; if (!PyUpb_Message_LookupName(self, attr, &field, NULL, PyExc_AttributeError)) { @@ -1850,7 +1833,15 @@ static PyObject* PyUpb_MessageMeta_New(PyTypeObject* type, PyObject* args, static void PyUpb_MessageMeta_Dealloc(PyObject* self) { PyUpb_MessageMeta* meta = PyUpb_GetMessageMeta(self); PyUpb_ObjCache_Delete(meta->layout); - Py_DECREF(meta->py_message_descriptor); + // The MessageMeta type is a GC type, which means we should untrack the + // object before invalidating internal state (so that code executed by the + // GC doesn't see the invalid state). Unfortunately since we're calling + // cpython_bits.type_dealloc, which also untracks the object, we can't. + // Instead just make sure the internal state remains reasonable by using + // Py_CLEAR(), which sets the struct member to NULL. The tp_traverse and + // tp_clear methods, which are called by Python's GC, already allow for it + // to be NULL. + Py_CLEAR(meta->py_message_descriptor); PyTypeObject* tp = Py_TYPE(self); cpython_bits.type_dealloc(self); Py_DECREF(tp); @@ -1948,6 +1939,8 @@ static int PyUpb_MessageMeta_Traverse(PyObject* self, visitproc visit, } static int PyUpb_MessageMeta_Clear(PyObject* self, visitproc visit, void* arg) { + PyUpb_MessageMeta* meta = PyUpb_GetMessageMeta(self); + Py_CLEAR(meta->py_message_descriptor); return cpython_bits.type_clear(self); } diff --git a/python/message.h b/python/message.h index d497f617f6..85e70a6dfe 100644 --- a/python/message.h +++ b/python/message.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef PYPB_MESSAGE_H__ #define PYPB_MESSAGE_H__ diff --git a/python/pb_unit_tests/pyproto_test_wrapper.bzl b/python/pb_unit_tests/pyproto_test_wrapper.bzl index bd5d0c0704..3ddf630295 100644 --- a/python/pb_unit_tests/pyproto_test_wrapper.bzl +++ b/python/pb_unit_tests/pyproto_test_wrapper.bzl @@ -25,7 +25,7 @@ def pyproto_test_wrapper(name, deps = []): # begin:google_only # -# load("//third_party/bazel_rules/rules_python/python:py_test.bzl", "py_test") +# load("@rules_python//python:py_test.bzl", "py_test") # # def pyproto_test_wrapper(name): # src = name + "_wrapper.py" diff --git a/python/protobuf.c b/python/protobuf.c index 324b1edb3e..4f53154dcb 100644 --- a/python/protobuf.c +++ b/python/protobuf.c @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "python/protobuf.h" diff --git a/python/protobuf.h b/python/protobuf.h index e9839be625..9c5894cbf9 100644 --- a/python/protobuf.h +++ b/python/protobuf.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef PYUPB_PROTOBUF_H__ #define PYUPB_PROTOBUF_H__ diff --git a/python/protobuf_distutils/setup.py b/python/protobuf_distutils/setup.py index f68b62b961..e7a499803b 100644 --- a/python/protobuf_distutils/setup.py +++ b/python/protobuf_distutils/setup.py @@ -34,6 +34,7 @@ setup( 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', 'Topic :: Software Development :: Code Generators', ], description=( diff --git a/python/py_extension.bzl b/python/py_extension.bzl index 1de830fb20..9a2828b950 100644 --- a/python/py_extension.bzl +++ b/python/py_extension.bzl @@ -54,5 +54,8 @@ def py_extension(name, srcs, copts, deps = [], **kwargs): name = name, data = [output_file], imports = ["."], - visibility = ["//python:__subpackages__"], + visibility = [ + "//python:__subpackages__", + "//conformance:__pkg__", + ], ) diff --git a/python/python_api.h b/python/python_api.h index fae7df263e..e94a6101ef 100644 --- a/python/python_api.h +++ b/python/python_api.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef PYUPB_PYTHON_H__ #define PYUPB_PYTHON_H__ diff --git a/python/repeated.c b/python/repeated.c index abb34e880a..57e347939b 100644 --- a/python/repeated.c +++ b/python/repeated.c @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "python/repeated.h" diff --git a/python/repeated.h b/python/repeated.h index 54670e7e80..08426a69e2 100644 --- a/python/repeated.h +++ b/python/repeated.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef PYUPB_REPEATED_H__ #define PYUPB_REPEATED_H__ diff --git a/python/requirements.txt b/python/requirements.txt index ad71bf28b1..d568cc581e 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -1 +1,2 @@ -numpy<=1.24.4 +numpy<=1.26.1 +setuptools<=68.2.2 diff --git a/python/setup.py b/python/setup.py index 057414d8fa..329dece306 100755 --- a/python/setup.py +++ b/python/setup.py @@ -389,7 +389,6 @@ if __name__ == '__main__': ]) os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp' - # Keep this list of dependencies in sync with tox.ini. install_requires = [] setup( @@ -415,6 +414,7 @@ if __name__ == '__main__': 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', ], namespace_packages=['google'], packages=find_packages( diff --git a/python/tox.ini b/python/tox.ini deleted file mode 100644 index 346ce21abd..0000000000 --- a/python/tox.ini +++ /dev/null @@ -1,21 +0,0 @@ -[tox] -envlist = - py{37,38,39,310}-{cpp,python} - -[testenv] -usedevelop=true -passenv = - CC PYTHONPATH KOKORO_BUILD_ID KOKORO_BUILD_NUMBER -setenv = - cpp: LD_LIBRARY_PATH={toxinidir}/../bazel-bin/src/google - cpp: DYLD_LIBRARY_PATH={toxinidir}/../bazel-bin/src/google - cpp: PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp - python: PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python -commands = - python setup.py -q build_py - python: python setup.py -q build - py{37,38,39,310}-cpp: python setup.py -q build --cpp_implementation --warnings_as_errors --compile_static_extension - python: python setup.py -q test -q - cpp: python setup.py -q test -q --cpp_implementation - python: python setup.py -q test_conformance - cpp: python setup.py -q test_conformance --cpp_implementation diff --git a/python/unknown_fields.c b/python/unknown_fields.c index f228f237b7..8017bd8943 100644 --- a/python/unknown_fields.c +++ b/python/unknown_fields.c @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #include "python/unknown_fields.h" diff --git a/python/unknown_fields.h b/python/unknown_fields.h index 85ea40c995..c9eae3b8ee 100644 --- a/python/unknown_fields.h +++ b/python/unknown_fields.h @@ -1,32 +1,9 @@ // Protocol Buffers - Google's data interchange format // Copyright 2023 Google LLC. All rights reserved. -// https://developers.google.com/protocol-buffers/ // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google LLC nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd #ifndef PYUPB_UNKNOWN_FIELDS_H__ #define PYUPB_UNKNOWN_FIELDS_H__ diff --git a/ruby/BUILD.bazel b/ruby/BUILD.bazel index cc4b477eed..ed9d1fd352 100755 --- a/ruby/BUILD.bazel +++ b/ruby/BUILD.bazel @@ -6,10 +6,10 @@ load("@bazel_skylib//lib:selects.bzl", "selects") load("@bazel_skylib//rules:common_settings.bzl", "string_flag") load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") load("@rules_ruby//ruby:defs.bzl", "ruby_library") -load("//build_defs:internal_shell.bzl", "inline_sh_binary") -load("//:protobuf.bzl", "internal_ruby_proto_library") -load("//conformance:defs.bzl", "conformance_test") +load("//python:internal.bzl", "internal_copy_files") +load("//ruby:defs.bzl", "internal_ruby_proto_library") load("//:protobuf_version.bzl", "PROTOBUF_RUBY_VERSION") +load("//conformance:defs.bzl", "conformance_test") ################################################################################ # Ruby Runtime @@ -86,6 +86,49 @@ selects.config_setting_group( ], ) +internal_copy_files( + name = "copied_wkt_proto_files", + srcs = [ + "//:well_known_type_protos", + "//src/google/protobuf:descriptor_proto_srcs", + "//src/google/protobuf/compiler:plugin.proto", + ], + strip_prefix = "src", +) + +internal_ruby_proto_library( + name = "well_known_ruby_protos", + srcs = [":copied_wkt_proto_files"], + default_runtime = "", + includes = ["."], + visibility = [ + "//conformance:__pkg__", + "//ruby:__subpackages__", + ], +) + +internal_copy_files( + name = "copied_conformance_test_files", + testonly = 1, + srcs = [ + "//src/google/protobuf:test_messages_proto2.proto", + "//src/google/protobuf:test_messages_proto3.proto", + ], + strip_prefix = "src", +) + +internal_ruby_proto_library( + name = "conformance_test_ruby_proto", + testonly = 1, + srcs = [":copied_conformance_test_files"], + includes = ["."], + visibility = [ + "//conformance:__pkg__", + "//ruby:__subpackages__", + ], + deps = [":well_known_ruby_protos"], +) + ruby_library( name = "protobuf", visibility = [ @@ -100,12 +143,12 @@ ruby_library( genrule( name = "jruby_release", srcs = [ - "@utf8_range//:utf8_range_srcs", - "@utf8_range//:LICENSE", + "//third_party/utf8_range:utf8_range_srcs", + "//third_party/utf8_range:LICENSE", "//ruby/lib/google:copy_jar", "//ruby/lib/google:dist_files", "//ruby/ext/google/protobuf_c:dist_files", - "//:well_known_ruby_protos", + ":well_known_ruby_protos", "google-protobuf.gemspec", ], outs = ["google-protobuf-" + PROTOBUF_RUBY_VERSION + "-java.gem"], @@ -116,10 +159,10 @@ genrule( cp --parents -L "$$src" tmp done mkdir -p "tmp/ruby/ext/google/protobuf_c/third_party/utf8_range" - for utf in $(execpaths @utf8_range//:utf8_range_srcs) $(execpath @utf8_range//:LICENSE); do + for utf in $(execpaths //third_party/utf8_range:utf8_range_srcs) $(execpath //third_party/utf8_range:LICENSE); do mv "tmp/$$utf" "tmp/ruby/ext/google/protobuf_c/third_party/utf8_range" done - for wkt in $(execpaths //:well_known_ruby_protos); do + for wkt in $(execpaths :well_known_ruby_protos); do mv "tmp/$$wkt" "tmp/ruby/lib/google/protobuf/" done mv "tmp/$(execpath //ruby/lib/google:copy_jar)" "tmp/ruby/lib/google" @@ -139,11 +182,11 @@ genrule( genrule( name = "ruby_release", srcs = [ - "@utf8_range//:utf8_range_srcs", - "@utf8_range//:LICENSE", - "//:well_known_ruby_protos", + "//third_party/utf8_range:utf8_range_srcs", + "//third_party/utf8_range:LICENSE", "//ruby/ext/google/protobuf_c:dist_files", "//ruby/lib/google:dist_files", + ":well_known_ruby_protos", "google-protobuf.gemspec", ], outs = ["google-protobuf-" + PROTOBUF_RUBY_VERSION + ".gem"], @@ -154,10 +197,10 @@ genrule( cp --parents -L "$$src" "tmp" done mkdir -p "tmp/ruby/ext/google/protobuf_c/third_party/utf8_range" - for utf in $(execpaths @utf8_range//:utf8_range_srcs) $(execpath @utf8_range//:LICENSE); do + for utf in $(execpaths //third_party/utf8_range:utf8_range_srcs) $(execpath //third_party/utf8_range:LICENSE); do mv "tmp/$$utf" "tmp/ruby/ext/google/protobuf_c/third_party/utf8_range" done - for wkt in $(execpaths //:well_known_ruby_protos); do + for wkt in $(execpaths :well_known_ruby_protos); do mv "tmp/$$wkt" "tmp/ruby/lib/google/protobuf/" done cd tmp/ruby @@ -198,7 +241,7 @@ internal_ruby_proto_library( visibility = [ "//ruby:__subpackages__", ], - deps = ["//:well_known_ruby_protos"], + deps = [":well_known_ruby_protos"], ) conformance_test( diff --git a/ruby/Rakefile b/ruby/Rakefile index 85a52dcf84..860bbc35fe 100644 --- a/ruby/Rakefile +++ b/ruby/Rakefile @@ -73,11 +73,7 @@ task :copy_third_party do unless File.exist? 'ext/google/protobuf_c/third_party/utf8_range' FileUtils.mkdir_p 'ext/google/protobuf_c/third_party/utf8_range' # We need utf8_range in-tree. - if ENV['BAZEL'] == 'true' - utf8_root = '../external/utf8_range' - else - utf8_root = '../third_party/utf8_range' - end + utf8_root = '../third_party/utf8_range' %w[ utf8_range.h naive.c range2-neon.c range2-neon.c range2-sse.c LICENSE ].each do |file| diff --git a/ruby/compatibility_tests/v3.0.0/tests/BUILD.bazel b/ruby/compatibility_tests/v3.0.0/tests/BUILD.bazel index 34a5391727..697f876991 100644 --- a/ruby/compatibility_tests/v3.0.0/tests/BUILD.bazel +++ b/ruby/compatibility_tests/v3.0.0/tests/BUILD.bazel @@ -1,6 +1,6 @@ load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix") load("@rules_ruby//ruby:defs.bzl", "ruby_test") -load("//:protobuf.bzl", "internal_ruby_proto_library") +load("//ruby:defs.bzl", "internal_ruby_proto_library") internal_ruby_proto_library( name = "test_ruby_protos", diff --git a/ruby/defs.bzl b/ruby/defs.bzl new file mode 100644 index 0000000000..7f60b47f5c --- /dev/null +++ b/ruby/defs.bzl @@ -0,0 +1,24 @@ +"""Wrapper around internal_ruby_proto_library to supply our rules_ruby""" + +load("@rules_ruby//ruby:defs.bzl", "ruby_library") +load("//:protobuf.bzl", _internal_ruby_proto_library = "internal_ruby_proto_library") + +def internal_ruby_proto_library( + name, + **kwargs): + """Bazel rule to create a Ruby protobuf library from proto source files + + NOTE: the rule is only an internal workaround to generate protos. The + interface may change and the rule may be removed when bazel has introduced + the native rule. + + Args: + name: the name of the ruby_proto_library. + **kwargs: other keyword arguments that are passed to ruby_library. + + """ + _internal_ruby_proto_library( + name, + ruby_library, + **kwargs + ) diff --git a/ruby/ext/google/protobuf_c/BUILD.bazel b/ruby/ext/google/protobuf_c/BUILD.bazel index 755a249ce1..391edaa65a 100644 --- a/ruby/ext/google/protobuf_c/BUILD.bazel +++ b/ruby/ext/google/protobuf_c/BUILD.bazel @@ -53,8 +53,8 @@ cc_library( "//conditions:default": [], }), deps = [ + "//third_party/utf8_range", "@rules_ruby//ruby/runtime:headers", - "@utf8_range", ], alwayslink = True, ) @@ -79,7 +79,7 @@ cc_library( "//conditions:default": [], }), deps = [ - "@utf8_range", + "//third_party/utf8_range", ], ) diff --git a/ruby/ext/google/protobuf_c/defs.c b/ruby/ext/google/protobuf_c/defs.c index ed1b9e17d2..ea91853215 100644 --- a/ruby/ext/google/protobuf_c/defs.c +++ b/ruby/ext/google/protobuf_c/defs.c @@ -44,7 +44,7 @@ static VALUE rb_str_maybe_null(const char* s) { } return rb_str_new2(s); } - +static ID options_instancevar_interned; // ----------------------------------------------------------------------------- // DescriptorPool. // ----------------------------------------------------------------------------- @@ -144,20 +144,26 @@ VALUE DescriptorPool_add_serialized_file(VALUE _self, * call-seq: * DescriptorPool.lookup(name) => descriptor * - * Finds a Descriptor or EnumDescriptor by name and returns it, or nil if none - * exists with the given name. + * Finds a Descriptor, EnumDescriptor or FieldDescriptor by name and returns it, + * or nil if none exists with the given name. */ static VALUE DescriptorPool_lookup(VALUE _self, VALUE name) { DescriptorPool* self = ruby_to_DescriptorPool(_self); const char* name_str = get_str(name); const upb_MessageDef* msgdef; const upb_EnumDef* enumdef; + const upb_FieldDef* fielddef; msgdef = upb_DefPool_FindMessageByName(self->symtab, name_str); if (msgdef) { return get_msgdef_obj(_self, msgdef); } + fielddef = upb_DefPool_FindExtensionByName(self->symtab, name_str); + if (fielddef) { + return get_fielddef_obj(_self, fielddef); + } + enumdef = upb_DefPool_FindEnumByName(self->symtab, name_str); if (enumdef) { return get_enumdef_obj(_self, enumdef); @@ -192,6 +198,7 @@ static void DescriptorPool_register(VALUE module) { rb_gc_register_address(&generated_pool); generated_pool = rb_class_new_instance(0, NULL, klass); + options_instancevar_interned = rb_intern("options"); } // ----------------------------------------------------------------------------- @@ -226,6 +233,35 @@ static Descriptor* ruby_to_Descriptor(VALUE val) { return ret; } +// Decode and return a frozen instance of a Descriptor Option for the given pool +static VALUE decode_options(VALUE self, const char* option_type, int size, + const char* bytes, VALUE descriptor_pool) { + VALUE options_rb = rb_ivar_get(self, options_instancevar_interned); + if (options_rb != Qnil) { + return options_rb; + } + + static const char* prefix = "google.protobuf."; + char fullname + [/*strlen(prefix)*/ 16 + + /*strln(longest option type supported e.g. "MessageOptions")*/ 14 + + /*null terminator*/ 1]; + + snprintf(fullname, sizeof(fullname), "%s%s", prefix, option_type); + const upb_MessageDef* msgdef = upb_DefPool_FindMessageByName( + ruby_to_DescriptorPool(descriptor_pool)->symtab, fullname); + if (!msgdef) { + rb_raise(rb_eRuntimeError, "Cannot find %s in DescriptorPool", option_type); + } + + VALUE desc_rb = get_msgdef_obj(descriptor_pool, msgdef); + const Descriptor* desc = ruby_to_Descriptor(desc_rb); + + options_rb = Message_decode_bytes(size, bytes, 0, desc->klass, true); + rb_ivar_set(self, options_instancevar_interned, options_rb); + return options_rb; +} + /* * call-seq: * Descriptor.new => descriptor @@ -374,6 +410,26 @@ static VALUE Descriptor_msgclass(VALUE _self) { return self->klass; } +/* + * call-seq: + * Descriptor.options => options + * + * Returns the `MessageOptions` for this `Descriptor`. + */ +static VALUE Descriptor_options(VALUE _self) { + Descriptor* self = ruby_to_Descriptor(_self); + const google_protobuf_MessageOptions* opts = + upb_MessageDef_Options(self->msgdef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = + google_protobuf_MessageOptions_serialize(opts, arena, &size); + VALUE message_options = decode_options(_self, "MessageOptions", size, + serialized, self->descriptor_pool); + upb_Arena_Free(arena); + return message_options; +} + static void Descriptor_register(VALUE module) { VALUE klass = rb_define_class_under(module, "Descriptor", rb_cObject); rb_define_alloc_func(klass, Descriptor_alloc); @@ -385,6 +441,7 @@ static void Descriptor_register(VALUE module) { rb_define_method(klass, "msgclass", Descriptor_msgclass, 0); rb_define_method(klass, "name", Descriptor_name, 0); rb_define_method(klass, "file_descriptor", Descriptor_file_descriptor, 0); + rb_define_method(klass, "options", Descriptor_options, 0); rb_include_module(klass, rb_mEnumerable); rb_gc_register_address(&cDescriptor); cDescriptor = klass; @@ -484,12 +541,31 @@ static VALUE FileDescriptor_syntax(VALUE _self) { } } +/* + * call-seq: + * FileDescriptor.options => options + * + * Returns the `FileOptions` for this `FileDescriptor`. + */ +static VALUE FileDescriptor_options(VALUE _self) { + FileDescriptor* self = ruby_to_FileDescriptor(_self); + const google_protobuf_FileOptions* opts = upb_FileDef_Options(self->filedef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = google_protobuf_FileOptions_serialize(opts, arena, &size); + VALUE file_options = decode_options(_self, "FileOptions", size, serialized, + self->descriptor_pool); + upb_Arena_Free(arena); + return file_options; +} + static void FileDescriptor_register(VALUE module) { VALUE klass = rb_define_class_under(module, "FileDescriptor", rb_cObject); rb_define_alloc_func(klass, FileDescriptor_alloc); rb_define_method(klass, "initialize", FileDescriptor_initialize, 3); rb_define_method(klass, "name", FileDescriptor_name, 0); rb_define_method(klass, "syntax", FileDescriptor_syntax, 0); + rb_define_method(klass, "options", FileDescriptor_options, 0); rb_gc_register_address(&cFileDescriptor); cFileDescriptor = klass; } @@ -540,7 +616,7 @@ static VALUE FieldDescriptor_alloc(VALUE klass) { /* * call-seq: - * EnumDescriptor.new(c_only_cookie, pool, ptr) => EnumDescriptor + * FieldDescriptor.new(c_only_cookie, pool, ptr) => FieldDescriptor * * Creates a descriptor wrapper object. May only be called from C. */ @@ -841,6 +917,25 @@ static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) { return Qnil; } +/* + * call-seq: + * FieldDescriptor.options => options + * + * Returns the `FieldOptions` for this `FieldDescriptor`. + */ +static VALUE FieldDescriptor_options(VALUE _self) { + FieldDescriptor* self = ruby_to_FieldDescriptor(_self); + const google_protobuf_FieldOptions* opts = + upb_FieldDef_Options(self->fielddef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, &size); + VALUE field_options = decode_options(_self, "FieldOptions", size, serialized, + self->descriptor_pool); + upb_Arena_Free(arena); + return field_options; +} + static void FieldDescriptor_register(VALUE module) { VALUE klass = rb_define_class_under(module, "FieldDescriptor", rb_cObject); rb_define_alloc_func(klass, FieldDescriptor_alloc); @@ -857,6 +952,7 @@ static void FieldDescriptor_register(VALUE module) { rb_define_method(klass, "clear", FieldDescriptor_clear, 1); rb_define_method(klass, "get", FieldDescriptor_get, 1); rb_define_method(klass, "set", FieldDescriptor_set, 2); + rb_define_method(klass, "options", FieldDescriptor_options, 0); rb_gc_register_address(&cFieldDescriptor); cFieldDescriptor = klass; } @@ -956,12 +1052,32 @@ static VALUE OneofDescriptor_each(VALUE _self) { return Qnil; } +/* + * call-seq: + * OneofDescriptor.options => options + * + * Returns the `OneofOptions` for this `OneofDescriptor`. + */ +static VALUE OneOfDescriptor_options(VALUE _self) { + OneofDescriptor* self = ruby_to_OneofDescriptor(_self); + const google_protobuf_OneofOptions* opts = + upb_OneofDef_Options(self->oneofdef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = google_protobuf_OneofOptions_serialize(opts, arena, &size); + VALUE oneof_options = decode_options(_self, "OneofOptions", size, serialized, + self->descriptor_pool); + upb_Arena_Free(arena); + return oneof_options; +} + static void OneofDescriptor_register(VALUE module) { VALUE klass = rb_define_class_under(module, "OneofDescriptor", rb_cObject); rb_define_alloc_func(klass, OneofDescriptor_alloc); rb_define_method(klass, "initialize", OneofDescriptor_initialize, 3); rb_define_method(klass, "name", OneofDescriptor_name, 0); rb_define_method(klass, "each", OneofDescriptor_each, 0); + rb_define_method(klass, "options", OneOfDescriptor_options, 0); rb_include_module(klass, rb_mEnumerable); rb_gc_register_address(&cOneofDescriptor); cOneofDescriptor = klass; @@ -1131,6 +1247,24 @@ static VALUE EnumDescriptor_enummodule(VALUE _self) { return self->module; } +/* + * call-seq: + * EnumDescriptor.options => options + * + * Returns the `EnumOptions` for this `EnumDescriptor`. + */ +static VALUE EnumDescriptor_options(VALUE _self) { + EnumDescriptor* self = ruby_to_EnumDescriptor(_self); + const google_protobuf_EnumOptions* opts = upb_EnumDef_Options(self->enumdef); + upb_Arena* arena = upb_Arena_New(); + size_t size; + char* serialized = google_protobuf_EnumOptions_serialize(opts, arena, &size); + VALUE enum_options = decode_options(_self, "EnumOptions", size, serialized, + self->descriptor_pool); + upb_Arena_Free(arena); + return enum_options; +} + static void EnumDescriptor_register(VALUE module) { VALUE klass = rb_define_class_under(module, "EnumDescriptor", rb_cObject); rb_define_alloc_func(klass, EnumDescriptor_alloc); @@ -1141,6 +1275,7 @@ static void EnumDescriptor_register(VALUE module) { rb_define_method(klass, "each", EnumDescriptor_each, 0); rb_define_method(klass, "enummodule", EnumDescriptor_enummodule, 0); rb_define_method(klass, "file_descriptor", EnumDescriptor_file_descriptor, 0); + rb_define_method(klass, "options", EnumDescriptor_options, 0); rb_include_module(klass, rb_mEnumerable); rb_gc_register_address(&cEnumDescriptor); cEnumDescriptor = klass; diff --git a/ruby/ext/google/protobuf_c/glue.c b/ruby/ext/google/protobuf_c/glue.c index 3505437c8b..e51e364279 100644 --- a/ruby/ext/google/protobuf_c/glue.c +++ b/ruby/ext/google/protobuf_c/glue.c @@ -14,8 +14,43 @@ upb_Arena* Arena_create() { return upb_Arena_Init(NULL, 0, &upb_alloc_global); } google_protobuf_FileDescriptorProto* FileDescriptorProto_parse( - const char* serialized_file_proto, size_t length) { - upb_Arena* arena = Arena_create(); + const char* serialized_file_proto, size_t length, upb_Arena* arena) { return google_protobuf_FileDescriptorProto_parse(serialized_file_proto, length, arena); } + +char* EnumDescriptor_serialized_options(const upb_EnumDef* enumdef, + size_t* size, upb_Arena* arena) { + const google_protobuf_EnumOptions* opts = upb_EnumDef_Options(enumdef); + char* serialized = google_protobuf_EnumOptions_serialize(opts, arena, size); + return serialized; +} + +char* FileDescriptor_serialized_options(const upb_FileDef* filedef, + size_t* size, upb_Arena* arena) { + const google_protobuf_FileOptions* opts = upb_FileDef_Options(filedef); + char* serialized = google_protobuf_FileOptions_serialize(opts, arena, size); + return serialized; +} + +char* Descriptor_serialized_options(const upb_MessageDef* msgdef, size_t* size, + upb_Arena* arena) { + const google_protobuf_MessageOptions* opts = upb_MessageDef_Options(msgdef); + char* serialized = + google_protobuf_MessageOptions_serialize(opts, arena, size); + return serialized; +} + +char* OneOfDescriptor_serialized_options(const upb_OneofDef* oneofdef, + size_t* size, upb_Arena* arena) { + const google_protobuf_OneofOptions* opts = upb_OneofDef_Options(oneofdef); + char* serialized = google_protobuf_OneofOptions_serialize(opts, arena, size); + return serialized; +} + +char* FieldDescriptor_serialized_options(const upb_FieldDef* fielddef, + size_t* size, upb_Arena* arena) { + const google_protobuf_FieldOptions* opts = upb_FieldDef_Options(fielddef); + char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, size); + return serialized; +} diff --git a/ruby/ext/google/protobuf_c/map.c b/ruby/ext/google/protobuf_c/map.c index 98ee489bc6..e3bd80c059 100644 --- a/ruby/ext/google/protobuf_c/map.c +++ b/ruby/ext/google/protobuf_c/map.c @@ -572,6 +572,26 @@ static VALUE Map_freeze(VALUE _self) { return _self; } +/* + * Deep freezes the map and values recursively. + * Internal use only. + */ +VALUE Map_internal_deep_freeze(VALUE _self) { + Map* self = ruby_to_Map(_self); + Map_freeze(_self); + if (self->value_type_info.type == kUpb_CType_Message) { + size_t iter = kUpb_Map_Begin; + upb_MessageValue key, val; + + while (upb_Map_Next(self->map, &key, &val, &iter)) { + VALUE val_val = + Convert_UpbToRuby(val, self->value_type_info, self->arena); + Message_internal_deep_freeze(val_val); + } + } + return _self; +} + /* * call-seq: * Map.hash => hash_value diff --git a/ruby/ext/google/protobuf_c/map.h b/ruby/ext/google/protobuf_c/map.h index 016a50c141..d3cebc6a69 100644 --- a/ruby/ext/google/protobuf_c/map.h +++ b/ruby/ext/google/protobuf_c/map.h @@ -38,4 +38,7 @@ extern VALUE cMap; // Call at startup to register all types in this module. void Map_register(VALUE module); +// Recursively freeze map +VALUE Map_internal_deep_freeze(VALUE _self); + #endif // RUBY_PROTOBUF_MAP_H_ diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c index a15e0fa098..dfb586e8e9 100644 --- a/ruby/ext/google/protobuf_c/message.c +++ b/ruby/ext/google/protobuf_c/message.c @@ -660,11 +660,8 @@ static VALUE Message_dup(VALUE _self) { Message* self = ruby_to_Message(_self); VALUE new_msg = rb_class_new_instance(0, NULL, CLASS_OF(_self)); Message* new_msg_self = ruby_to_Message(new_msg); - size_t size = upb_MessageDef_MiniTable(self->msgdef)->size; - - // TODO - // TODO - memcpy((upb_Message*)new_msg_self->msg, self->msg, size); + const upb_MiniTable* m = upb_MessageDef_MiniTable(self->msgdef); + upb_Message_ShallowCopy((upb_Message*)new_msg_self->msg, self->msg, m); Arena_fuse(self->arena, Arena_get(new_msg_self->arena)); return new_msg; } @@ -859,6 +856,32 @@ static VALUE Message_freeze(VALUE _self) { return _self; } +/* + * Deep freezes the message object recursively. + * Internal use only. + */ +VALUE Message_internal_deep_freeze(VALUE _self) { + Message* self = ruby_to_Message(_self); + Message_freeze(_self); + + int n = upb_MessageDef_FieldCount(self->msgdef); + for (int i = 0; i < n; i++) { + const upb_FieldDef* f = upb_MessageDef_Field(self->msgdef, i); + VALUE field = Message_getfield(_self, f); + + if (field != Qnil) { + if (upb_FieldDef_IsMap(f)) { + Map_internal_deep_freeze(field); + } else if (upb_FieldDef_IsRepeated(f)) { + RepeatedField_internal_deep_freeze(field); + } else if (upb_FieldDef_IsSubMessage(f)) { + Message_internal_deep_freeze(field); + } + } + } + return _self; +} + /* * call-seq: * Message.[](index) => value @@ -911,7 +934,7 @@ static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) { * MessageClass.decode(data, options) => message * * Decodes the given data (as a string containing bytes in protocol buffers wire - * format) under the interpretration given by this message class's definition + * format) under the interpretation given by this message class's definition * and returns a message object with the corresponding field values. * @param options [Hash] options for the decoder * recursion_limit: set to maximum decoding depth for message (default is 64) @@ -942,18 +965,27 @@ static VALUE Message_decode(int argc, VALUE* argv, VALUE klass) { rb_raise(rb_eArgError, "Expected string for binary protobuf data."); } + return Message_decode_bytes(RSTRING_LEN(data), RSTRING_PTR(data), options, + klass, /*freeze*/ false); +} + +VALUE Message_decode_bytes(int size, const char* bytes, int options, + VALUE klass, bool freeze) { VALUE msg_rb = initialize_rb_class_with_no_args(klass); Message* msg = ruby_to_Message(msg_rb); - upb_DecodeStatus status = - upb_Decode(RSTRING_PTR(data), RSTRING_LEN(data), (upb_Message*)msg->msg, - upb_MessageDef_MiniTable(msg->msgdef), NULL, options, - Arena_get(msg->arena)); - + const upb_FileDef* file = upb_MessageDef_File(msg->msgdef); + const upb_ExtensionRegistry* extreg = + upb_DefPool_ExtensionRegistry(upb_FileDef_Pool(file)); + upb_DecodeStatus status = upb_Decode(bytes, size, (upb_Message*)msg->msg, + upb_MessageDef_MiniTable(msg->msgdef), + extreg, options, Arena_get(msg->arena)); if (status != kUpb_DecodeStatus_Ok) { rb_raise(cParseError, "Error occurred during parsing"); } - + if (freeze) { + Message_internal_deep_freeze(msg_rb); + } return msg_rb; } @@ -1271,9 +1303,12 @@ upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m, upb_Message* new_msg = upb_Message_New(layout, arena); char* data; + const upb_FileDef* file = upb_MessageDef_File(m); + const upb_ExtensionRegistry* extreg = + upb_DefPool_ExtensionRegistry(upb_FileDef_Pool(file)); if (upb_Encode(msg, layout, 0, tmp_arena, &data, &size) != kUpb_EncodeStatus_Ok || - upb_Decode(data, size, new_msg, layout, NULL, 0, arena) != + upb_Decode(data, size, new_msg, layout, extreg, 0, arena) != kUpb_DecodeStatus_Ok) { upb_Arena_Free(tmp_arena); rb_raise(cParseError, "Error occurred copying proto"); diff --git a/ruby/ext/google/protobuf_c/message.h b/ruby/ext/google/protobuf_c/message.h index 5e354b05d7..cb6897f0d4 100644 --- a/ruby/ext/google/protobuf_c/message.h +++ b/ruby/ext/google/protobuf_c/message.h @@ -73,6 +73,13 @@ VALUE build_module_from_enumdesc(VALUE _enumdesc); // module. VALUE MessageOrEnum_GetDescriptor(VALUE klass); +// Decodes a Message from a byte sequence. +VALUE Message_decode_bytes(int size, const char* bytes, int options, + VALUE klass, bool freeze); + +// Recursively freeze message +VALUE Message_internal_deep_freeze(VALUE _self); + // Call at startup to register all types in this module. void Message_register(VALUE protobuf); diff --git a/ruby/ext/google/protobuf_c/repeated_field.c b/ruby/ext/google/protobuf_c/repeated_field.c index f5ca3cae46..1960126749 100644 --- a/ruby/ext/google/protobuf_c/repeated_field.c +++ b/ruby/ext/google/protobuf_c/repeated_field.c @@ -487,6 +487,25 @@ static VALUE RepeatedField_freeze(VALUE _self) { return _self; } +/* + * Deep freezes the repeated field and values recursively. + * Internal use only. + */ +VALUE RepeatedField_internal_deep_freeze(VALUE _self) { + RepeatedField* self = ruby_to_RepeatedField(_self); + RepeatedField_freeze(_self); + if (self->type_info.type == kUpb_CType_Message) { + int size = upb_Array_Size(self->array); + int i; + for (i = 0; i < size; i++) { + upb_MessageValue msgval = upb_Array_Get(self->array, i); + VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena); + Message_internal_deep_freeze(val); + } + } + return _self; +} + /* * call-seq: * RepeatedField.hash => hash_value diff --git a/ruby/ext/google/protobuf_c/repeated_field.h b/ruby/ext/google/protobuf_c/repeated_field.h index 97a908e6d6..f3f7a50cd5 100644 --- a/ruby/ext/google/protobuf_c/repeated_field.h +++ b/ruby/ext/google/protobuf_c/repeated_field.h @@ -35,4 +35,7 @@ extern VALUE cRepeatedField; // Call at startup to register all types in this module. void RepeatedField_register(VALUE module); +// Recursively freeze RepeatedField. +VALUE RepeatedField_internal_deep_freeze(VALUE _self); + #endif // RUBY_PROTOBUF_REPEATED_FIELD_H_ diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c index 8790a0e32d..965581d1b3 100644 --- a/ruby/ext/google/protobuf_c/ruby-upb.c +++ b/ruby/ext/google/protobuf_c/ruby-upb.c @@ -181,6 +181,12 @@ Error, UINTPTR_MAX is undefined #define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only +#ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY +#define UPB_ONLYBITS(x) x +#else +#define UPB_ONLYBITS(x) UPB_PRIVATE(x) +#endif + /* Configure whether fasttable is switched on or not. *************************/ #ifdef __has_attribute @@ -319,8 +325,13 @@ void __asan_unpoison_memory_region(void const volatile *addr, size_t size); #if defined(UPB_IS_GOOGLE3) && !defined(UPB_BOOTSTRAP_STAGE0) #define UPB_DESC(sym) proto2_##sym +#define UPB_DESC_MINITABLE(sym) &proto2__##sym##_msg_init +#elif defined(UPB_BOOTSTRAP_STAGE0) +#define UPB_DESC(sym) google_protobuf_##sym +#define UPB_DESC_MINITABLE(sym) google__protobuf__##sym##_msg_init() #else #define UPB_DESC(sym) google_protobuf_##sym +#define UPB_DESC_MINITABLE(sym) &google__protobuf__##sym##_msg_init #endif @@ -387,7 +398,7 @@ void upb_Status_VAppendErrorFormat(upb_Status* status, const char* fmt, // Must be last. static const upb_MiniTableSub google_protobuf_FileDescriptorSet_submsgs[1] = { - {.submsg = &google__protobuf__FileDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FileDescriptorProto_msg_init}, }; static const upb_MiniTableField google_protobuf_FileDescriptorSet__fields[1] = { @@ -405,13 +416,13 @@ const upb_MiniTable google__protobuf__FileDescriptorSet_msg_init = { }; static const upb_MiniTableSub google_protobuf_FileDescriptorProto_submsgs[7] = { - {.submsg = &google__protobuf__DescriptorProto_msg_init}, - {.submsg = &google__protobuf__EnumDescriptorProto_msg_init}, - {.submsg = &google__protobuf__ServiceDescriptorProto_msg_init}, - {.submsg = &google__protobuf__FieldDescriptorProto_msg_init}, - {.submsg = &google__protobuf__FileOptions_msg_init}, - {.submsg = &google__protobuf__SourceCodeInfo_msg_init}, - {.subenum = &google_protobuf_Edition_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__DescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__ServiceDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FileOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__SourceCodeInfo_msg_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_Edition_enum_init}, }; static const upb_MiniTableField google_protobuf_FileDescriptorProto__fields[13] = { @@ -455,14 +466,14 @@ const upb_MiniTable google__protobuf__FileDescriptorProto_msg_init = { }; static const upb_MiniTableSub google_protobuf_DescriptorProto_submsgs[8] = { - {.submsg = &google__protobuf__FieldDescriptorProto_msg_init}, - {.submsg = &google__protobuf__DescriptorProto_msg_init}, - {.submsg = &google__protobuf__EnumDescriptorProto_msg_init}, - {.submsg = &google__protobuf__DescriptorProto__ExtensionRange_msg_init}, - {.submsg = &google__protobuf__FieldDescriptorProto_msg_init}, - {.submsg = &google__protobuf__MessageOptions_msg_init}, - {.submsg = &google__protobuf__OneofDescriptorProto_msg_init}, - {.submsg = &google__protobuf__DescriptorProto__ReservedRange_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__DescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__DescriptorProto__ExtensionRange_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__MessageOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__OneofDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__DescriptorProto__ReservedRange_msg_init}, }; static const upb_MiniTableField google_protobuf_DescriptorProto__fields[10] = { @@ -503,7 +514,7 @@ const upb_MiniTable google__protobuf__DescriptorProto_msg_init = { }; static const upb_MiniTableSub google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = { - {.submsg = &google__protobuf__ExtensionRangeOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__ExtensionRangeOptions_msg_init}, }; static const upb_MiniTableField google_protobuf_DescriptorProto_ExtensionRange__fields[3] = { @@ -542,10 +553,10 @@ const upb_MiniTable google__protobuf__DescriptorProto__ReservedRange_msg_init = }; static const upb_MiniTableSub google_protobuf_ExtensionRangeOptions_submsgs[4] = { - {.submsg = &google__protobuf__ExtensionRangeOptions__Declaration_msg_init}, - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, - {.subenum = &google_protobuf_ExtensionRangeOptions_VerificationState_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__ExtensionRangeOptions__Declaration_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_ExtensionRangeOptions_VerificationState_enum_init}, }; static const upb_MiniTableField google_protobuf_ExtensionRangeOptions__fields[4] = { @@ -620,9 +631,9 @@ const upb_MiniTable google__protobuf__ExtensionRangeOptions__Declaration_msg_ini }; static const upb_MiniTableSub google_protobuf_FieldDescriptorProto_submsgs[3] = { - {.submsg = &google__protobuf__FieldOptions_msg_init}, - {.subenum = &google_protobuf_FieldDescriptorProto_Label_enum_init}, - {.subenum = &google_protobuf_FieldDescriptorProto_Type_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldOptions_msg_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FieldDescriptorProto_Label_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FieldDescriptorProto_Type_enum_init}, }; static const upb_MiniTableField google_protobuf_FieldDescriptorProto__fields[11] = { @@ -680,7 +691,7 @@ const upb_MiniTable google__protobuf__FieldDescriptorProto_msg_init = { }; static const upb_MiniTableSub google_protobuf_OneofDescriptorProto_submsgs[1] = { - {.submsg = &google__protobuf__OneofOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__OneofOptions_msg_init}, }; static const upb_MiniTableField google_protobuf_OneofDescriptorProto__fields[2] = { @@ -701,9 +712,9 @@ const upb_MiniTable google__protobuf__OneofDescriptorProto_msg_init = { }; static const upb_MiniTableSub google_protobuf_EnumDescriptorProto_submsgs[3] = { - {.submsg = &google__protobuf__EnumValueDescriptorProto_msg_init}, - {.submsg = &google__protobuf__EnumOptions_msg_init}, - {.submsg = &google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumValueDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init}, }; static const upb_MiniTableField google_protobuf_EnumDescriptorProto__fields[5] = { @@ -748,7 +759,7 @@ const upb_MiniTable google__protobuf__EnumDescriptorProto__EnumReservedRange_msg }; static const upb_MiniTableSub google_protobuf_EnumValueDescriptorProto_submsgs[1] = { - {.submsg = &google__protobuf__EnumValueOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__EnumValueOptions_msg_init}, }; static const upb_MiniTableField google_protobuf_EnumValueDescriptorProto__fields[3] = { @@ -770,8 +781,8 @@ const upb_MiniTable google__protobuf__EnumValueDescriptorProto_msg_init = { }; static const upb_MiniTableSub google_protobuf_ServiceDescriptorProto_submsgs[2] = { - {.submsg = &google__protobuf__MethodDescriptorProto_msg_init}, - {.submsg = &google__protobuf__ServiceOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__MethodDescriptorProto_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__ServiceOptions_msg_init}, }; static const upb_MiniTableField google_protobuf_ServiceDescriptorProto__fields[3] = { @@ -793,7 +804,7 @@ const upb_MiniTable google__protobuf__ServiceDescriptorProto_msg_init = { }; static const upb_MiniTableSub google_protobuf_MethodDescriptorProto_submsgs[1] = { - {.submsg = &google__protobuf__MethodOptions_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__MethodOptions_msg_init}, }; static const upb_MiniTableField google_protobuf_MethodDescriptorProto__fields[6] = { @@ -822,9 +833,9 @@ const upb_MiniTable google__protobuf__MethodDescriptorProto_msg_init = { }; static const upb_MiniTableSub google_protobuf_FileOptions_submsgs[3] = { - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, - {.subenum = &google_protobuf_FileOptions_OptimizeMode_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FileOptions_OptimizeMode_enum_init}, }; static const upb_MiniTableField google_protobuf_FileOptions__fields[22] = { @@ -893,8 +904,8 @@ const upb_MiniTable google__protobuf__FileOptions_msg_init = { }; static const upb_MiniTableSub google_protobuf_MessageOptions_submsgs[2] = { - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, }; static const upb_MiniTableField google_protobuf_MessageOptions__fields[7] = { @@ -948,13 +959,13 @@ const upb_MiniTable google__protobuf__MessageOptions_msg_init = { }; static const upb_MiniTableSub google_protobuf_FieldOptions_submsgs[7] = { - {.submsg = &google__protobuf__FieldOptions__EditionDefault_msg_init}, - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, - {.subenum = &google_protobuf_FieldOptions_CType_enum_init}, - {.subenum = &google_protobuf_FieldOptions_JSType_enum_init}, - {.subenum = &google_protobuf_FieldOptions_OptionRetention_enum_init}, - {.subenum = &google_protobuf_FieldOptions_OptionTargetType_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FieldOptions__EditionDefault_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FieldOptions_CType_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FieldOptions_JSType_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FieldOptions_OptionRetention_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FieldOptions_OptionTargetType_enum_init}, }; static const upb_MiniTableField google_protobuf_FieldOptions__fields[13] = { @@ -1014,7 +1025,7 @@ const upb_MiniTable google__protobuf__FieldOptions_msg_init = { }; static const upb_MiniTableSub google_protobuf_FieldOptions_EditionDefault_submsgs[1] = { - {.subenum = &google_protobuf_Edition_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_Edition_enum_init}, }; static const upb_MiniTableField google_protobuf_FieldOptions_EditionDefault__fields[2] = { @@ -1035,8 +1046,8 @@ const upb_MiniTable google__protobuf__FieldOptions__EditionDefault_msg_init = { }; static const upb_MiniTableSub google_protobuf_OneofOptions_submsgs[2] = { - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, }; static const upb_MiniTableField google_protobuf_OneofOptions__fields[2] = { @@ -1085,8 +1096,8 @@ const upb_MiniTable google__protobuf__OneofOptions_msg_init = { }; static const upb_MiniTableSub google_protobuf_EnumOptions_submsgs[2] = { - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, }; static const upb_MiniTableField google_protobuf_EnumOptions__fields[5] = { @@ -1138,8 +1149,8 @@ const upb_MiniTable google__protobuf__EnumOptions_msg_init = { }; static const upb_MiniTableSub google_protobuf_EnumValueOptions_submsgs[2] = { - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, }; static const upb_MiniTableField google_protobuf_EnumValueOptions__fields[4] = { @@ -1190,8 +1201,8 @@ const upb_MiniTable google__protobuf__EnumValueOptions_msg_init = { }; static const upb_MiniTableSub google_protobuf_ServiceOptions_submsgs[2] = { - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, }; static const upb_MiniTableField google_protobuf_ServiceOptions__fields[3] = { @@ -1241,9 +1252,9 @@ const upb_MiniTable google__protobuf__ServiceOptions_msg_init = { }; static const upb_MiniTableSub google_protobuf_MethodOptions_submsgs[3] = { - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.submsg = &google__protobuf__UninterpretedOption_msg_init}, - {.subenum = &google_protobuf_MethodOptions_IdempotencyLevel_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption_msg_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_MethodOptions_IdempotencyLevel_enum_init}, }; static const upb_MiniTableField google_protobuf_MethodOptions__fields[4] = { @@ -1294,7 +1305,7 @@ const upb_MiniTable google__protobuf__MethodOptions_msg_init = { }; static const upb_MiniTableSub google_protobuf_UninterpretedOption_submsgs[1] = { - {.submsg = &google__protobuf__UninterpretedOption__NamePart_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__UninterpretedOption__NamePart_msg_init}, }; static const upb_MiniTableField google_protobuf_UninterpretedOption__fields[7] = { @@ -1349,12 +1360,12 @@ const upb_MiniTable google__protobuf__UninterpretedOption__NamePart_msg_init = { }; static const upb_MiniTableSub google_protobuf_FeatureSet_submsgs[6] = { - {.subenum = &google_protobuf_FeatureSet_FieldPresence_enum_init}, - {.subenum = &google_protobuf_FeatureSet_EnumType_enum_init}, - {.subenum = &google_protobuf_FeatureSet_RepeatedFieldEncoding_enum_init}, - {.subenum = &google_protobuf_FeatureSet_Utf8Validation_enum_init}, - {.subenum = &google_protobuf_FeatureSet_MessageEncoding_enum_init}, - {.subenum = &google_protobuf_FeatureSet_JsonFormat_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FeatureSet_FieldPresence_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FeatureSet_EnumType_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FeatureSet_RepeatedFieldEncoding_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FeatureSet_Utf8Validation_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FeatureSet_MessageEncoding_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_FeatureSet_JsonFormat_enum_init}, }; static const upb_MiniTableField google_protobuf_FeatureSet__fields[6] = { @@ -1373,9 +1384,9 @@ const upb_MiniTable google__protobuf__FeatureSet_msg_init = { }; static const upb_MiniTableSub google_protobuf_FeatureSetDefaults_submsgs[3] = { - {.submsg = &google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init}, - {.subenum = &google_protobuf_Edition_enum_init}, - {.subenum = &google_protobuf_Edition_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_Edition_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_Edition_enum_init}, }; static const upb_MiniTableField google_protobuf_FeatureSetDefaults__fields[3] = { @@ -1395,8 +1406,8 @@ const upb_MiniTable google__protobuf__FeatureSetDefaults_msg_init = { }; static const upb_MiniTableSub google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault_submsgs[2] = { - {.submsg = &google__protobuf__FeatureSet_msg_init}, - {.subenum = &google_protobuf_Edition_enum_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__FeatureSet_msg_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_Edition_enum_init}, }; static const upb_MiniTableField google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault__fields[2] = { @@ -1417,7 +1428,7 @@ const upb_MiniTable google__protobuf__FeatureSetDefaults__FeatureSetEditionDefau }; static const upb_MiniTableSub google_protobuf_SourceCodeInfo_submsgs[1] = { - {.submsg = &google__protobuf__SourceCodeInfo__Location_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__SourceCodeInfo__Location_msg_init}, }; static const upb_MiniTableField google_protobuf_SourceCodeInfo__fields[1] = { @@ -1459,7 +1470,7 @@ const upb_MiniTable google__protobuf__SourceCodeInfo__Location_msg_init = { }; static const upb_MiniTableSub google_protobuf_GeneratedCodeInfo_submsgs[1] = { - {.submsg = &google__protobuf__GeneratedCodeInfo__Annotation_msg_init}, + {.UPB_PRIVATE(submsg) = &google__protobuf__GeneratedCodeInfo__Annotation_msg_init}, }; static const upb_MiniTableField google_protobuf_GeneratedCodeInfo__fields[1] = { @@ -1477,7 +1488,7 @@ const upb_MiniTable google__protobuf__GeneratedCodeInfo_msg_init = { }; static const upb_MiniTableSub google_protobuf_GeneratedCodeInfo_Annotation_submsgs[1] = { - {.subenum = &google_protobuf_GeneratedCodeInfo_Annotation_Semantic_enum_init}, + {.UPB_PRIVATE(subenum) = &google_protobuf_GeneratedCodeInfo_Annotation_Semantic_enum_init}, }; static const upb_MiniTableField google_protobuf_GeneratedCodeInfo_Annotation__fields[5] = { @@ -1541,7 +1552,7 @@ static const upb_MiniTable *messages_layout[32] = { const upb_MiniTableEnum google_protobuf_Edition_enum_init = { 64, - 6, + 7, { 0x7, 0x0, @@ -1551,6 +1562,7 @@ const upb_MiniTableEnum google_protobuf_Edition_enum_init = { 0x1869d, 0x1869e, 0x1869f, + 0x7fffffff, }, }; @@ -1612,7 +1624,7 @@ const upb_MiniTableEnum google_protobuf_FeatureSet_Utf8Validation_enum_init = { 64, 0, { - 0x7, + 0xd, 0x0, }, }; @@ -2574,6 +2586,10 @@ void upb_strtable_setentryvalue(upb_strtable* t, intptr_t iter, upb_value v) { #include #include #include +#include +#include +#include +#include #include #include @@ -2622,9 +2638,13 @@ static bool jsondec_isvalue(const upb_FieldDef* f) { jsondec_isnullvalue(f); } -UPB_NORETURN static void jsondec_err(jsondec* d, const char* msg) { +static void jsondec_seterrmsg(jsondec* d, const char* msg) { upb_Status_SetErrorFormat(d->status, "Error parsing JSON @%d:%d: %s", d->line, (int)(d->ptr - d->line_begin), msg); +} + +UPB_NORETURN static void jsondec_err(jsondec* d, const char* msg) { + jsondec_seterrmsg(d, msg); UPB_LONGJMP(d->err, 1); } @@ -2639,7 +2659,9 @@ UPB_NORETURN static void jsondec_errf(jsondec* d, const char* fmt, ...) { UPB_LONGJMP(d->err, 1); } -static void jsondec_skipws(jsondec* d) { +// Advances d->ptr until the next non-whitespace character or to the end of +// the buffer. +static void jsondec_consumews(jsondec* d) { while (d->ptr != d->end) { switch (*d->ptr) { case '\n': @@ -2655,7 +2677,16 @@ static void jsondec_skipws(jsondec* d) { return; } } - jsondec_err(d, "Unexpected EOF"); +} + +// Advances d->ptr until the next non-whitespace character. Postcondition that +// d->ptr is pointing at a valid non-whitespace character (will err if end of +// buffer is reached). +static void jsondec_skipws(jsondec* d) { + jsondec_consumews(d); + if (d->ptr == d->end) { + jsondec_err(d, "Unexpected EOF"); + } } static bool jsondec_tryparsech(jsondec* d, char ch) { @@ -2690,6 +2721,10 @@ static void jsondec_entrysep(jsondec* d) { } static int jsondec_rawpeek(jsondec* d) { + if (d->ptr == d->end) { + jsondec_err(d, "Unexpected EOF"); + } + switch (*d->ptr) { case '{': return JD_OBJECT; @@ -2805,7 +2840,7 @@ static void jsondec_skipdigits(jsondec* d) { static double jsondec_number(jsondec* d) { const char* start = d->ptr; - assert(jsondec_rawpeek(d) == JD_NUMBER); + UPB_ASSERT(jsondec_rawpeek(d) == JD_NUMBER); /* Skip over the syntax of a number, as specified by JSON. */ if (*d->ptr == '-') d->ptr++; @@ -2840,9 +2875,19 @@ parse: * (strtod() accepts a superset of JSON syntax). */ errno = 0; { + // Copy the number into a null-terminated scratch buffer since strtod + // expects a null-terminated string. + char nullz[64]; + ptrdiff_t len = d->ptr - start; + if (len > (ptrdiff_t)(sizeof(nullz) - 1)) { + jsondec_err(d, "excessively long number"); + } + memcpy(nullz, start, len); + nullz[len] = '\0'; + char* end; - double val = strtod(start, &end); - assert(end == d->ptr); + double val = strtod(nullz, &end); + UPB_ASSERT(end - nullz == len); /* Currently the min/max-val conformance tests fail if we check this. Does * this mean the conformance tests are wrong or strtod() is wrong, or @@ -2983,7 +3028,7 @@ static upb_StringView jsondec_string(jsondec* d) { } break; default: - if ((unsigned char)*d->ptr < 0x20) { + if ((unsigned char)ch < 0x20) { jsondec_err(d, "Invalid char in JSON string"); } *end++ = ch; @@ -3987,7 +4032,17 @@ static bool upb_JsonDecoder_Decode(jsondec* const d, upb_Message* const msg, if (UPB_SETJMP(d->err)) return false; jsondec_tomsg(d, msg, m); - return true; + + // Consume any trailing whitespace before checking if we read the entire + // input. + jsondec_consumews(d); + + if (d->ptr == d->end) { + return true; + } else { + jsondec_seterrmsg(d, "unexpected trailing characters"); + return false; + } } bool upb_JsonDecode(const char* buf, size_t size, upb_Message* msg, @@ -5341,32 +5396,33 @@ void upb_Arena_DecRefFor(upb_Arena* arena, const void* owner) { } +#include + // Must be last. upb_MapInsertStatus upb_Message_InsertMapEntry(upb_Map* map, const upb_MiniTable* mini_table, - const upb_MiniTableField* field, + const upb_MiniTableField* f, upb_Message* map_entry_message, upb_Arena* arena) { - const upb_MiniTable* map_entry_mini_table = - mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg; + // TODO: use a variant of upb_MiniTable_GetSubMessageTable() here. + const upb_MiniTable* map_entry_mini_table = upb_MiniTableSub_Message( + mini_table->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); UPB_ASSERT(map_entry_mini_table); - UPB_ASSERT(map_entry_mini_table->field_count == 2); + UPB_ASSERT(map_entry_mini_table->UPB_PRIVATE(field_count) == 2); const upb_MiniTableField* map_entry_key_field = - &map_entry_mini_table->fields[0]; + &map_entry_mini_table->UPB_PRIVATE(fields)[0]; const upb_MiniTableField* map_entry_value_field = - &map_entry_mini_table->fields[1]; + &map_entry_mini_table->UPB_PRIVATE(fields)[1]; // Map key/value cannot have explicit defaults, // hence assuming a zero default is valid. upb_MessageValue default_val; memset(&default_val, 0, sizeof(upb_MessageValue)); - upb_MessageValue map_entry_key; - upb_MessageValue map_entry_value; - _upb_Message_GetField(map_entry_message, map_entry_key_field, &default_val, - &map_entry_key); - _upb_Message_GetField(map_entry_message, map_entry_value_field, &default_val, - &map_entry_value); + upb_MessageValue map_entry_key = + upb_Message_GetField(map_entry_message, map_entry_key_field, default_val); + upb_MessageValue map_entry_value = upb_Message_GetField( + map_entry_message, map_entry_value_field, default_val); return upb_Map_Insert(map, map_entry_key, map_entry_value, arena); } @@ -5395,26 +5451,312 @@ bool upb_Message_IsExactlyEqual(const upb_Message* m1, const upb_Message* m2, } +#include #include + // Must be last. -const char _upb_Array_CTypeSizeLg2Table[] = { - [kUpb_CType_Bool] = 0, - [kUpb_CType_Float] = 2, - [kUpb_CType_Int32] = 2, - [kUpb_CType_UInt32] = 2, - [kUpb_CType_Enum] = 2, - [kUpb_CType_Message] = UPB_SIZE(2, 3), - [kUpb_CType_Double] = 3, - [kUpb_CType_Int64] = 3, - [kUpb_CType_UInt64] = 3, - [kUpb_CType_String] = UPB_SIZE(3, 4), - [kUpb_CType_Bytes] = UPB_SIZE(3, 4), -}; +static upb_StringView upb_Clone_StringView(upb_StringView str, + upb_Arena* arena) { + if (str.size == 0) { + return upb_StringView_FromDataAndSize(NULL, 0); + } + void* cloned_data = upb_Arena_Malloc(arena, str.size); + upb_StringView cloned_str = + upb_StringView_FromDataAndSize(cloned_data, str.size); + memcpy(cloned_data, str.data, str.size); + return cloned_str; +} + +static bool upb_Clone_MessageValue(void* value, upb_CType value_type, + const upb_MiniTable* sub, upb_Arena* arena) { + switch (value_type) { + case kUpb_CType_Bool: + case kUpb_CType_Float: + case kUpb_CType_Int32: + case kUpb_CType_UInt32: + case kUpb_CType_Enum: + case kUpb_CType_Double: + case kUpb_CType_Int64: + case kUpb_CType_UInt64: + return true; + case kUpb_CType_String: + case kUpb_CType_Bytes: { + upb_StringView source = *(upb_StringView*)value; + int size = source.size; + void* cloned_data = upb_Arena_Malloc(arena, size); + if (cloned_data == NULL) { + return false; + } + *(upb_StringView*)value = + upb_StringView_FromDataAndSize(cloned_data, size); + memcpy(cloned_data, source.data, size); + return true; + } break; + case kUpb_CType_Message: { + const upb_TaggedMessagePtr source = *(upb_TaggedMessagePtr*)value; + bool is_empty = upb_TaggedMessagePtr_IsEmpty(source); + if (is_empty) sub = UPB_PRIVATE(_upb_MiniTable_Empty)(); + UPB_ASSERT(source); + upb_Message* clone = upb_Message_DeepClone( + _upb_TaggedMessagePtr_GetMessage(source), sub, arena); + *(upb_TaggedMessagePtr*)value = + _upb_TaggedMessagePtr_Pack(clone, is_empty); + return clone != NULL; + } break; + } + UPB_UNREACHABLE(); +} + +upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type, + upb_CType value_type, + const upb_MiniTable* map_entry_table, + upb_Arena* arena) { + upb_Map* cloned_map = _upb_Map_New(arena, map->key_size, map->val_size); + if (cloned_map == NULL) { + return NULL; + } + upb_MessageValue key, val; + size_t iter = kUpb_Map_Begin; + while (upb_Map_Next(map, &key, &val, &iter)) { + const upb_MiniTableField* value_field = + &map_entry_table->UPB_PRIVATE(fields)[1]; + const upb_MiniTable* value_sub = + (value_field->UPB_PRIVATE(submsg_index) != kUpb_NoSub) + ? upb_MiniTable_GetSubMessageTable(map_entry_table, value_field) + : NULL; + upb_CType value_field_type = upb_MiniTableField_CType(value_field); + if (!upb_Clone_MessageValue(&val, value_field_type, value_sub, arena)) { + return NULL; + } + if (upb_Map_Insert(cloned_map, key, val, arena) == + kUpb_MapInsertStatus_OutOfMemory) { + return NULL; + } + } + return cloned_map; +} + +static upb_Map* upb_Message_Map_DeepClone(const upb_Map* map, + const upb_MiniTable* mini_table, + const upb_MiniTableField* f, + upb_Message* clone, + upb_Arena* arena) { + // TODO: use a variant of upb_MiniTable_GetSubMessageTable() here. + const upb_MiniTable* map_entry_table = upb_MiniTableSub_Message( + mini_table->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); + UPB_ASSERT(map_entry_table); + + const upb_MiniTableField* key_field = + &map_entry_table->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* value_field = + &map_entry_table->UPB_PRIVATE(fields)[1]; + + upb_Map* cloned_map = upb_Map_DeepClone( + map, upb_MiniTableField_CType(key_field), + upb_MiniTableField_CType(value_field), map_entry_table, arena); + if (!cloned_map) { + return NULL; + } + _upb_Message_SetNonExtensionField(clone, f, &cloned_map); + return cloned_map; +} + +upb_Array* upb_Array_DeepClone(const upb_Array* array, upb_CType value_type, + const upb_MiniTable* sub, upb_Arena* arena) { + size_t size = array->size; + upb_Array* cloned_array = + UPB_PRIVATE(_upb_Array_New)(arena, size, upb_CType_SizeLg2(value_type)); + if (!cloned_array) { + return NULL; + } + if (!_upb_Array_ResizeUninitialized(cloned_array, size, arena)) { + return NULL; + } + for (size_t i = 0; i < size; ++i) { + upb_MessageValue val = upb_Array_Get(array, i); + if (!upb_Clone_MessageValue(&val, value_type, sub, arena)) { + return false; + } + upb_Array_Set(cloned_array, i, val); + } + return cloned_array; +} + +static bool upb_Message_Array_DeepClone(const upb_Array* array, + const upb_MiniTable* mini_table, + const upb_MiniTableField* field, + upb_Message* clone, upb_Arena* arena) { + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(field); + upb_Array* cloned_array = upb_Array_DeepClone( + array, upb_MiniTableField_CType(field), + upb_MiniTableField_CType(field) == kUpb_CType_Message && + field->UPB_PRIVATE(submsg_index) != kUpb_NoSub + ? upb_MiniTable_GetSubMessageTable(mini_table, field) + : NULL, + arena); + + // Clear out upb_Array* due to parent memcpy. + _upb_Message_SetNonExtensionField(clone, field, &cloned_array); + return true; +} + +static bool upb_Clone_ExtensionValue( + const upb_MiniTableExtension* mini_table_ext, + const upb_Message_Extension* source, upb_Message_Extension* dest, + upb_Arena* arena) { + dest->data = source->data; + return upb_Clone_MessageValue( + &dest->data, + upb_MiniTableField_CType(&mini_table_ext->UPB_PRIVATE(field)), + upb_MiniTableExtension_GetSubMessage(mini_table_ext), arena); +} + +upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* mini_table, + upb_Arena* arena) { + upb_StringView empty_string = upb_StringView_FromDataAndSize(NULL, 0); + // Only copy message area skipping upb_Message_Internal. + memcpy(dst, src, mini_table->UPB_PRIVATE(size)); + for (size_t i = 0; i < mini_table->UPB_PRIVATE(field_count); ++i) { + const upb_MiniTableField* field = &mini_table->UPB_PRIVATE(fields)[i]; + if (upb_MiniTableField_IsScalar(field)) { + switch (upb_MiniTableField_CType(field)) { + case kUpb_CType_Message: { + upb_TaggedMessagePtr tagged = + upb_Message_GetTaggedMessagePtr(src, field, NULL); + const upb_Message* sub_message = + _upb_TaggedMessagePtr_GetMessage(tagged); + if (sub_message != NULL) { + // If the message is currently in an unlinked, "empty" state we keep + // it that way, because we don't want to deal with decode options, + // decode status, or possible parse failure here. + bool is_empty = upb_TaggedMessagePtr_IsEmpty(tagged); + const upb_MiniTable* sub_message_table = + is_empty ? UPB_PRIVATE(_upb_MiniTable_Empty)() + : upb_MiniTable_GetSubMessageTable(mini_table, field); + upb_Message* dst_sub_message = + upb_Message_DeepClone(sub_message, sub_message_table, arena); + if (dst_sub_message == NULL) { + return NULL; + } + _upb_Message_SetTaggedMessagePtr( + dst, mini_table, field, + _upb_TaggedMessagePtr_Pack(dst_sub_message, is_empty)); + } + } break; + case kUpb_CType_String: + case kUpb_CType_Bytes: { + upb_StringView str = upb_Message_GetString(src, field, empty_string); + if (str.size != 0) { + if (!upb_Message_SetString( + dst, field, upb_Clone_StringView(str, arena), arena)) { + return NULL; + } + } + } break; + default: + // Scalar, already copied. + break; + } + } else { + if (upb_MiniTableField_IsMap(field)) { + const upb_Map* map = upb_Message_GetMap(src, field); + if (map != NULL) { + if (!upb_Message_Map_DeepClone(map, mini_table, field, dst, arena)) { + return NULL; + } + } + } else { + const upb_Array* array = upb_Message_GetArray(src, field); + if (array != NULL) { + if (!upb_Message_Array_DeepClone(array, mini_table, field, dst, + arena)) { + return NULL; + } + } + } + } + } + // Clone extensions. + size_t ext_count; + const upb_Message_Extension* ext = _upb_Message_Getexts(src, &ext_count); + for (size_t i = 0; i < ext_count; ++i) { + const upb_Message_Extension* msg_ext = &ext[i]; + const upb_MiniTableField* field = &msg_ext->ext->UPB_PRIVATE(field); + upb_Message_Extension* dst_ext = + _upb_Message_GetOrCreateExtension(dst, msg_ext->ext, arena); + if (!dst_ext) return NULL; + if (upb_MiniTableField_IsScalar(field)) { + if (!upb_Clone_ExtensionValue(msg_ext->ext, msg_ext, dst_ext, arena)) { + return NULL; + } + } else { + upb_Array* msg_array = (upb_Array*)msg_ext->data.ptr; + UPB_ASSERT(msg_array); + upb_Array* cloned_array = upb_Array_DeepClone( + msg_array, upb_MiniTableField_CType(field), + upb_MiniTableExtension_GetSubMessage(msg_ext->ext), arena); + if (!cloned_array) { + return NULL; + } + dst_ext->data.ptr = (void*)cloned_array; + } + } + + // Clone unknowns. + size_t unknown_size = 0; + const char* ptr = upb_Message_GetUnknown(src, &unknown_size); + if (unknown_size != 0) { + UPB_ASSERT(ptr); + // Make a copy into destination arena. + if (!UPB_PRIVATE(_upb_Message_AddUnknown)(dst, ptr, unknown_size, arena)) { + return NULL; + } + } + return dst; +} + +bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* mini_table, upb_Arena* arena) { + upb_Message_Clear(dst, mini_table); + return _upb_Message_Copy(dst, src, mini_table, arena) != NULL; +} + +// Deep clones a message using the provided target arena. +// +// Returns NULL on failure. +upb_Message* upb_Message_DeepClone(const upb_Message* msg, + const upb_MiniTable* m, upb_Arena* arena) { + upb_Message* clone = upb_Message_New(m, arena); + return _upb_Message_Copy(clone, msg, m, arena); +} + +// Performs a shallow copy. TODO: Extend to handle unknown fields. +void upb_Message_ShallowCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* m) { + memcpy(dst, src, m->UPB_PRIVATE(size)); +} + +// Performs a shallow clone. Ignores unknown fields. +upb_Message* upb_Message_ShallowClone(const upb_Message* msg, + const upb_MiniTable* m, + upb_Arena* arena) { + upb_Message* clone = upb_Message_New(m, arena); + upb_Message_ShallowCopy(clone, msg, m); + return clone; +} + + +#include +#include + + +// Must be last. upb_Array* upb_Array_New(upb_Arena* a, upb_CType type) { - return _upb_Array_New(a, 4, _upb_Array_CTypeSizeLg2(type)); + return UPB_PRIVATE(_upb_Array_New)(a, 4, upb_CType_SizeLg2(type)); } const void* upb_Array_DataPtr(const upb_Array* arr) { @@ -5428,7 +5770,7 @@ size_t upb_Array_Size(const upb_Array* arr) { return arr->size; } upb_MessageValue upb_Array_Get(const upb_Array* arr, size_t i) { upb_MessageValue ret; const char* data = _upb_array_constptr(arr); - int lg2 = arr->data & 7; + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr); UPB_ASSERT(i < arr->size); memcpy(&ret, data + (i << lg2), 1 << lg2); return ret; @@ -5436,14 +5778,14 @@ upb_MessageValue upb_Array_Get(const upb_Array* arr, size_t i) { void upb_Array_Set(upb_Array* arr, size_t i, upb_MessageValue val) { char* data = _upb_array_ptr(arr); - int lg2 = arr->data & 7; + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr); UPB_ASSERT(i < arr->size); memcpy(data + (i << lg2), &val, 1 << lg2); } bool upb_Array_Append(upb_Array* arr, upb_MessageValue val, upb_Arena* arena) { UPB_ASSERT(arena); - if (!upb_Array_Resize(arr, arr->size + 1, arena)) { + if (!_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } upb_Array_Set(arr, arr->size - 1, val); @@ -5452,7 +5794,7 @@ bool upb_Array_Append(upb_Array* arr, upb_MessageValue val, upb_Arena* arena) { void upb_Array_Move(upb_Array* arr, size_t dst_idx, size_t src_idx, size_t count) { - const int lg2 = arr->data & 7; + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr); char* data = _upb_array_ptr(arr); memmove(&data[dst_idx << lg2], &data[src_idx << lg2], count << lg2); } @@ -5463,7 +5805,7 @@ bool upb_Array_Insert(upb_Array* arr, size_t i, size_t count, UPB_ASSERT(i <= arr->size); UPB_ASSERT(count + arr->size >= count); const size_t oldsize = arr->size; - if (!upb_Array_Resize(arr, arr->size + count, arena)) { + if (!_upb_Array_ResizeUninitialized(arr, arr->size + count, arena)) { return false; } upb_Array_Move(arr, i + count, i, oldsize - i); @@ -5489,31 +5831,125 @@ bool upb_Array_Resize(upb_Array* arr, size_t size, upb_Arena* arena) { } const size_t newsize = arr->size; if (newsize > oldsize) { - const int lg2 = arr->data & 7; + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(arr); char* data = _upb_array_ptr(arr); memset(data + (oldsize << lg2), 0, (newsize - oldsize) << lg2); } return true; } -// EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// - -bool _upb_array_realloc(upb_Array* arr, size_t min_capacity, upb_Arena* arena) { - size_t new_capacity = UPB_MAX(arr->capacity, 4); - int elem_size_lg2 = arr->data & 7; - size_t old_bytes = arr->capacity << elem_size_lg2; - size_t new_bytes; - void* ptr = _upb_array_ptr(arr); +bool UPB_PRIVATE(_upb_Array_Realloc)(upb_Array* array, size_t min_capacity, + upb_Arena* arena) { + size_t new_capacity = UPB_MAX(array->UPB_PRIVATE(capacity), 4); + const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(array); + size_t old_bytes = array->UPB_PRIVATE(capacity) << lg2; + void* ptr = _upb_array_ptr(array); // Log2 ceiling of size. while (new_capacity < min_capacity) new_capacity *= 2; - new_bytes = new_capacity << elem_size_lg2; + const size_t new_bytes = new_capacity << lg2; ptr = upb_Arena_Realloc(arena, ptr, old_bytes, new_bytes); if (!ptr) return false; - arr->data = _upb_tag_arrptr(ptr, elem_size_lg2); - arr->capacity = new_capacity; + UPB_PRIVATE(_upb_Array_SetTaggedPtr)(array, ptr, lg2); + array->UPB_PRIVATE(capacity) = new_capacity; + return true; +} + + +#include + + +// Must be last. + +const upb_Message_Extension* _upb_Message_Getext( + const upb_Message* msg, const upb_MiniTableExtension* e) { + size_t n; + const upb_Message_Extension* ext = _upb_Message_Getexts(msg, &n); + + // For now we use linear search exclusively to find extensions. + // If this becomes an issue due to messages with lots of extensions, + // we can introduce a table of some sort. + for (size_t i = 0; i < n; i++) { + if (ext[i].ext == e) { + return &ext[i]; + } + } + + return NULL; +} + +const upb_Message_Extension* _upb_Message_Getexts(const upb_Message* msg, + size_t* count) { + const upb_Message_Internal* in = upb_Message_Getinternal(msg); + if (in->internal) { + *count = (in->internal->size - in->internal->ext_begin) / + sizeof(upb_Message_Extension); + return UPB_PTR_AT(in->internal, in->internal->ext_begin, void); + } else { + *count = 0; + return NULL; + } +} + +upb_Message_Extension* _upb_Message_GetOrCreateExtension( + upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* arena) { + upb_Message_Extension* ext = + (upb_Message_Extension*)_upb_Message_Getext(msg, e); + if (ext) return ext; + if (!UPB_PRIVATE(_upb_Message_Realloc)(msg, sizeof(upb_Message_Extension), arena)) return NULL; + upb_Message_Internal* in = upb_Message_Getinternal(msg); + in->internal->ext_begin -= sizeof(upb_Message_Extension); + ext = UPB_PTR_AT(in->internal, in->internal->ext_begin, void); + memset(ext, 0, sizeof(upb_Message_Extension)); + ext->ext = e; + return ext; +} + + +#include +#include + + +// Must be last. + +const float kUpb_FltInfinity = INFINITY; +const double kUpb_Infinity = INFINITY; +const double kUpb_NaN = NAN; + +static const size_t realloc_overhead = sizeof(upb_Message_InternalData); + +bool UPB_PRIVATE(_upb_Message_Realloc)(upb_Message* msg, size_t need, + upb_Arena* arena) { + upb_Message_Internal* in = upb_Message_Getinternal(msg); + if (!in->internal) { + // No internal data, allocate from scratch. + size_t size = UPB_MAX(128, upb_Log2CeilingSize(need + realloc_overhead)); + upb_Message_InternalData* internal = upb_Arena_Malloc(arena, size); + if (!internal) return false; + internal->size = size; + internal->unknown_end = realloc_overhead; + internal->ext_begin = size; + in->internal = internal; + } else if (in->internal->ext_begin - in->internal->unknown_end < need) { + // Internal data is too small, reallocate. + size_t new_size = upb_Log2CeilingSize(in->internal->size + need); + size_t ext_bytes = in->internal->size - in->internal->ext_begin; + size_t new_ext_begin = new_size - ext_bytes; + upb_Message_InternalData* internal = + upb_Arena_Realloc(arena, in->internal, in->internal->size, new_size); + if (!internal) return false; + if (ext_bytes) { + // Need to move extension data to the end. + char* ptr = (char*)internal; + memmove(ptr + new_ext_begin, ptr + internal->ext_begin, ext_bytes); + } + internal->ext_begin = new_ext_begin; + internal->size = new_size; + in->internal = internal; + } + UPB_ASSERT(in->internal->ext_begin - in->internal->unknown_end >= need); return true; } @@ -5630,6 +6066,9 @@ upb_Map* _upb_Map_New(upb_Arena* a, size_t key_size, size_t value_size) { } +#include +#include + // Must be last. @@ -5711,8 +6150,10 @@ static bool _upb_mapsorter_resize(_upb_mapsorter* s, _upb_sortedmap* sorted, sorted->end = sorted->start + size; if (sorted->end > s->cap) { + const int oldsize = s->cap * sizeof(*s->entries); s->cap = upb_Log2CeilingSize(sorted->end); - s->entries = realloc(s->entries, s->cap * sizeof(*s->entries)); + const int newsize = s->cap * sizeof(*s->entries); + s->entries = upb_grealloc(s->entries, oldsize, newsize); if (!s->entries) return false; } @@ -5747,8 +6188,8 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type, static int _upb_mapsorter_cmpext(const void* _a, const void* _b) { const upb_Message_Extension* const* a = _a; const upb_Message_Extension* const* b = _b; - uint32_t a_num = (*a)->ext->field.number; - uint32_t b_num = (*b)->ext->field.number; + uint32_t a_num = upb_MiniTableExtension_Number((*a)->ext); + uint32_t b_num = upb_MiniTableExtension_Number((*b)->ext); assert(a_num != b_num); return a_num < b_num ? -1 : 1; } @@ -5768,57 +6209,22 @@ bool _upb_mapsorter_pushexts(_upb_mapsorter* s, } -#include +#include +#include +#include // Must be last. -const float kUpb_FltInfinity = INFINITY; -const double kUpb_Infinity = INFINITY; -const double kUpb_NaN = NAN; - -static const size_t overhead = sizeof(upb_Message_InternalData); +static const size_t message_overhead = sizeof(upb_Message_InternalData); -upb_Message* upb_Message_New(const upb_MiniTable* mini_table, - upb_Arena* arena) { - return _upb_Message_New(mini_table, arena); +upb_Message* upb_Message_New(const upb_MiniTable* m, upb_Arena* arena) { + return _upb_Message_New(m, arena); } -static bool realloc_internal(upb_Message* msg, size_t need, upb_Arena* arena) { - upb_Message_Internal* in = upb_Message_Getinternal(msg); - if (!in->internal) { - /* No internal data, allocate from scratch. */ - size_t size = UPB_MAX(128, upb_Log2CeilingSize(need + overhead)); - upb_Message_InternalData* internal = upb_Arena_Malloc(arena, size); - if (!internal) return false; - internal->size = size; - internal->unknown_end = overhead; - internal->ext_begin = size; - in->internal = internal; - } else if (in->internal->ext_begin - in->internal->unknown_end < need) { - /* Internal data is too small, reallocate. */ - size_t new_size = upb_Log2CeilingSize(in->internal->size + need); - size_t ext_bytes = in->internal->size - in->internal->ext_begin; - size_t new_ext_begin = new_size - ext_bytes; - upb_Message_InternalData* internal = - upb_Arena_Realloc(arena, in->internal, in->internal->size, new_size); - if (!internal) return false; - if (ext_bytes) { - /* Need to move extension data to the end. */ - char* ptr = (char*)internal; - memmove(ptr + new_ext_begin, ptr + internal->ext_begin, ext_bytes); - } - internal->ext_begin = new_ext_begin; - internal->size = new_size; - in->internal = internal; - } - UPB_ASSERT(in->internal->ext_begin - in->internal->unknown_end >= need); - return true; -} - -bool _upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len, - upb_Arena* arena) { - if (!realloc_internal(msg, len, arena)) return false; +bool UPB_PRIVATE(_upb_Message_AddUnknown)(upb_Message* msg, const char* data, + size_t len, upb_Arena* arena) { + if (!UPB_PRIVATE(_upb_Message_Realloc)(msg, len, arena)) return false; upb_Message_Internal* in = upb_Message_Getinternal(msg); memcpy(UPB_PTR_AT(in->internal, in->internal->unknown_end, char), data, len); in->internal->unknown_end += len; @@ -5828,14 +6234,14 @@ bool _upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len, void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) { upb_Message_Internal* in = upb_Message_Getinternal(msg); if (in->internal) { - in->internal->unknown_end = overhead; + in->internal->unknown_end = message_overhead; } } const char* upb_Message_GetUnknown(const upb_Message* msg, size_t* len) { const upb_Message_Internal* in = upb_Message_Getinternal(msg); if (in->internal) { - *len = in->internal->unknown_end - overhead; + *len = in->internal->unknown_end - message_overhead; return (char*)(in->internal + 1); } else { *len = 0; @@ -5861,50 +6267,6 @@ void upb_Message_DeleteUnknown(upb_Message* msg, const char* data, size_t len) { in->internal->unknown_end -= len; } -const upb_Message_Extension* _upb_Message_Getexts(const upb_Message* msg, - size_t* count) { - const upb_Message_Internal* in = upb_Message_Getinternal(msg); - if (in->internal) { - *count = (in->internal->size - in->internal->ext_begin) / - sizeof(upb_Message_Extension); - return UPB_PTR_AT(in->internal, in->internal->ext_begin, void); - } else { - *count = 0; - return NULL; - } -} - -const upb_Message_Extension* _upb_Message_Getext( - const upb_Message* msg, const upb_MiniTableExtension* e) { - size_t n; - const upb_Message_Extension* ext = _upb_Message_Getexts(msg, &n); - - /* For now we use linear search exclusively to find extensions. If this - * becomes an issue due to messages with lots of extensions, we can introduce - * a table of some sort. */ - for (size_t i = 0; i < n; i++) { - if (ext[i].ext == e) { - return &ext[i]; - } - } - - return NULL; -} - -upb_Message_Extension* _upb_Message_GetOrCreateExtension( - upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* arena) { - upb_Message_Extension* ext = - (upb_Message_Extension*)_upb_Message_Getext(msg, e); - if (ext) return ext; - if (!realloc_internal(msg, sizeof(upb_Message_Extension), arena)) return NULL; - upb_Message_Internal* in = upb_Message_Getinternal(msg); - in->internal->ext_begin -= sizeof(upb_Message_Extension); - ext = UPB_PTR_AT(in->internal, in->internal->ext_begin, void); - memset(ext, 0, sizeof(upb_Message_Extension)); - ext->ext = e; - return ext; -} - size_t upb_Message_ExtensionCount(const upb_Message* msg) { size_t count; _upb_Message_Getexts(msg, &count); @@ -5912,6 +6274,9 @@ size_t upb_Message_ExtensionCount(const upb_Message* msg) { } +#include +#include + // Must be last. @@ -5937,26 +6302,27 @@ static upb_MiniTableEnum* _upb_MiniTable_AddEnumDataMember(upb_MdEnumDecoder* d, d->enum_table = upb_Arena_Realloc(d->arena, d->enum_table, old_sz, new_sz); upb_MdDecoder_CheckOutOfMemory(&d->base, d->enum_table); } - d->enum_table->data[d->enum_data_count++] = val; + d->enum_table->UPB_PRIVATE(data)[d->enum_data_count++] = val; return d->enum_table; } static void upb_MiniTableEnum_BuildValue(upb_MdEnumDecoder* d, uint32_t val) { upb_MiniTableEnum* table = d->enum_table; d->enum_value_count++; - if (table->value_count || (val > 512 && d->enum_value_count < val / 32)) { - if (table->value_count == 0) { - assert(d->enum_data_count == table->mask_limit / 32); + if (table->UPB_PRIVATE(value_count) || + (val > 512 && d->enum_value_count < val / 32)) { + if (table->UPB_PRIVATE(value_count) == 0) { + UPB_ASSERT(d->enum_data_count == table->UPB_PRIVATE(mask_limit) / 32); } table = _upb_MiniTable_AddEnumDataMember(d, val); - table->value_count++; + table->UPB_PRIVATE(value_count)++; } else { uint32_t new_mask_limit = ((val / 32) + 1) * 32; - while (table->mask_limit < new_mask_limit) { + while (table->UPB_PRIVATE(mask_limit) < new_mask_limit) { table = _upb_MiniTable_AddEnumDataMember(d, 0); - table->mask_limit += 32; + table->UPB_PRIVATE(mask_limit) += 32; } - table->data[val / 32] |= 1ULL << (val % 32); + table->UPB_PRIVATE(data)[val / 32] |= 1ULL << (val % 32); } } @@ -5974,11 +6340,11 @@ static upb_MiniTableEnum* upb_MtDecoder_DoBuildMiniTableEnum( upb_MdDecoder_CheckOutOfMemory(&d->base, d->enum_table); // Guarantee at least 64 bits of mask without checking mask size. - d->enum_table->mask_limit = 64; + d->enum_table->UPB_PRIVATE(mask_limit) = 64; d->enum_table = _upb_MiniTable_AddEnumDataMember(d, 0); d->enum_table = _upb_MiniTable_AddEnumDataMember(d, 0); - d->enum_table->value_count = 0; + d->enum_table->UPB_PRIVATE(value_count) = 0; const char* ptr = data; uint32_t base = 0; @@ -6006,7 +6372,8 @@ static upb_MiniTableEnum* upb_MtDecoder_DoBuildMiniTableEnum( } static upb_MiniTableEnum* upb_MtDecoder_BuildMiniTableEnum( - upb_MdEnumDecoder* const decoder, const char* const data, size_t const len) { + upb_MdEnumDecoder* const decoder, const char* const data, + size_t const len) { if (UPB_SETJMP(decoder->base.err) != 0) return NULL; return upb_MtDecoder_DoBuildMiniTableEnum(decoder, data, len); } @@ -6032,6 +6399,7 @@ upb_MiniTableEnum* upb_MiniDescriptor_BuildEnum(const char* data, size_t len, #include +#include #include @@ -6084,7 +6452,7 @@ enum PresenceClass { }; static bool upb_MtDecoder_FieldIsPackable(upb_MiniTableField* field) { - return (field->mode & kUpb_FieldMode_Array) && + return (field->UPB_PRIVATE(mode) & kUpb_FieldMode_Array) && upb_FieldType_IsPackable(field->UPB_PRIVATE(descriptortype)); } @@ -6101,18 +6469,18 @@ static void upb_MiniTable_SetTypeAndSub(upb_MiniTableField* field, if (is_proto3_enum) { UPB_ASSERT(type == kUpb_FieldType_Enum); type = kUpb_FieldType_Int32; - field->mode |= kUpb_LabelFlags_IsAlternate; + field->UPB_PRIVATE(mode) |= kUpb_LabelFlags_IsAlternate; } else if (type == kUpb_FieldType_String && !(msg_modifiers & kUpb_MessageModifier_ValidateUtf8)) { type = kUpb_FieldType_Bytes; - field->mode |= kUpb_LabelFlags_IsAlternate; + field->UPB_PRIVATE(mode) |= kUpb_LabelFlags_IsAlternate; } field->UPB_PRIVATE(descriptortype) = type; if (upb_MtDecoder_FieldIsPackable(field) && (msg_modifiers & kUpb_MessageModifier_DefaultIsPacked)) { - field->mode |= kUpb_LabelFlags_IsPacked; + field->UPB_PRIVATE(mode) |= kUpb_LabelFlags_IsPacked; } if (type == kUpb_FieldType_Message || type == kUpb_FieldType_Group) { @@ -6179,18 +6547,19 @@ static void upb_MiniTable_SetField(upb_MtDecoder* d, uint8_t ch, int8_t type = _upb_FromBase92(ch); if (ch >= _upb_ToBase92(kUpb_EncodedType_RepeatedBase)) { type -= kUpb_EncodedType_RepeatedBase; - field->mode = kUpb_FieldMode_Array; - field->mode |= pointer_rep << kUpb_FieldRep_Shift; + field->UPB_PRIVATE(mode) = kUpb_FieldMode_Array; + field->UPB_PRIVATE(mode) |= pointer_rep << kUpb_FieldRep_Shift; field->offset = kNoPresence; } else { - field->mode = kUpb_FieldMode_Scalar; + field->UPB_PRIVATE(mode) = kUpb_FieldMode_Scalar; field->offset = kHasbitPresence; if (type == kUpb_EncodedType_Group || type == kUpb_EncodedType_Message) { - field->mode |= pointer_rep << kUpb_FieldRep_Shift; + field->UPB_PRIVATE(mode) |= pointer_rep << kUpb_FieldRep_Shift; } else if ((unsigned long)type >= sizeof(kUpb_EncodedToFieldRep)) { upb_MdDecoder_ErrorJmp(&d->base, "Invalid field type: %d", (int)type); } else { - field->mode |= kUpb_EncodedToFieldRep[type] << kUpb_FieldRep_Shift; + field->UPB_PRIVATE(mode) |= kUpb_EncodedToFieldRep[type] + << kUpb_FieldRep_Shift; } } if ((unsigned long)type >= sizeof(kUpb_EncodedToType)) { @@ -6208,22 +6577,23 @@ static void upb_MtDecoder_ModifyField(upb_MtDecoder* d, if (!upb_MtDecoder_FieldIsPackable(field)) { upb_MdDecoder_ErrorJmp(&d->base, "Cannot flip packed on unpackable field %" PRIu32, - field->number); + upb_MiniTableField_Number(field)); } - field->mode ^= kUpb_LabelFlags_IsPacked; + field->UPB_PRIVATE(mode) ^= kUpb_LabelFlags_IsPacked; } if (field_modifiers & kUpb_EncodedFieldModifier_FlipValidateUtf8) { if (field->UPB_PRIVATE(descriptortype) != kUpb_FieldType_Bytes || - !(field->mode & kUpb_LabelFlags_IsAlternate)) { - upb_MdDecoder_ErrorJmp( - &d->base, - "Cannot flip ValidateUtf8 on field %" PRIu32 ", type=%d, mode=%d", - field->number, (int)field->UPB_PRIVATE(descriptortype), - (int)field->mode); + !(field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsAlternate)) { + upb_MdDecoder_ErrorJmp(&d->base, + "Cannot flip ValidateUtf8 on field %" PRIu32 + ", type=%d, mode=%d", + upb_MiniTableField_Number(field), + (int)field->UPB_PRIVATE(descriptortype), + (int)field->UPB_PRIVATE(mode)); } field->UPB_PRIVATE(descriptortype) = kUpb_FieldType_String; - field->mode &= ~kUpb_LabelFlags_IsAlternate; + field->UPB_PRIVATE(mode) &= ~kUpb_LabelFlags_IsAlternate; } bool singular = field_modifiers & kUpb_EncodedFieldModifier_IsProto3Singular; @@ -6233,12 +6603,12 @@ static void upb_MtDecoder_ModifyField(upb_MtDecoder* d, if ((singular || required) && field->offset != kHasbitPresence) { upb_MdDecoder_ErrorJmp(&d->base, "Invalid modifier(s) for repeated field %" PRIu32, - field->number); + upb_MiniTableField_Number(field)); } if (singular && required) { upb_MdDecoder_ErrorJmp( &d->base, "Field %" PRIu32 " cannot be both singular and required", - field->number); + upb_MiniTableField_Number(field)); } if (singular) field->offset = kNoPresence; @@ -6339,7 +6709,7 @@ static const char* upb_MtDecoder_DecodeOneofField(upb_MtDecoder* d, } // Oneof storage must be large enough to accommodate the largest member. - int rep = f->mode >> kUpb_FieldRep_Shift; + int rep = f->UPB_PRIVATE(mode) >> kUpb_FieldRep_Shift; if (upb_MtDecoder_SizeOfRep(rep, d->platform) > upb_MtDecoder_SizeOfRep(item->rep, d->platform)) { item->rep = rep; @@ -6396,26 +6766,26 @@ static const char* upb_MtDecoder_ParseModifier(upb_MtDecoder* d, static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d, upb_SubCounts sub_counts) { uint32_t total_count = sub_counts.submsg_count + sub_counts.subenum_count; - size_t subs_bytes = sizeof(*d->table->subs) * total_count; + size_t subs_bytes = sizeof(*d->table->UPB_PRIVATE(subs)) * total_count; upb_MiniTableSub* subs = upb_Arena_Malloc(d->arena, subs_bytes); upb_MdDecoder_CheckOutOfMemory(&d->base, subs); uint32_t i = 0; for (; i < sub_counts.submsg_count; i++) { - subs[i].submsg = &_kUpb_MiniTable_Empty; + subs[i].UPB_PRIVATE(submsg) = UPB_PRIVATE(_upb_MiniTable_Empty)(); } if (sub_counts.subenum_count) { upb_MiniTableField* f = d->fields; - upb_MiniTableField* end_f = f + d->table->field_count; + upb_MiniTableField* end_f = f + d->table->UPB_PRIVATE(field_count); for (; f < end_f; f++) { if (f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum) { f->UPB_PRIVATE(submsg_index) += sub_counts.submsg_count; } } for (; i < sub_counts.submsg_count + sub_counts.subenum_count; i++) { - subs[i].subenum = NULL; + subs[i].UPB_PRIVATE(subenum) = NULL; } } - d->table->subs = subs; + d->table->UPB_PRIVATE(subs) = subs; } static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, @@ -6439,14 +6809,14 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, upb_MiniTableField* field = fields; *field_count += 1; fields = (char*)fields + field_size; - field->number = ++last_field_number; + field->UPB_PRIVATE(number) = ++last_field_number; last_field = field; upb_MiniTable_SetField(d, ch, field, msg_modifiers, sub_counts); } else if (kUpb_EncodedValue_MinModifier <= ch && ch <= kUpb_EncodedValue_MaxModifier) { ptr = upb_MtDecoder_ParseModifier(d, ptr, ch, last_field, &msg_modifiers); if (msg_modifiers & kUpb_MessageModifier_IsExtendable) { - d->table->ext |= kUpb_ExtMode_Extendable; + d->table->UPB_PRIVATE(ext) |= kUpb_ExtMode_Extendable; } } else if (ch == kUpb_EncodedValue_End) { if (!d->table) { @@ -6456,7 +6826,7 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, } else if (kUpb_EncodedValue_MinSkip <= ch && ch <= kUpb_EncodedValue_MaxSkip) { if (need_dense_below) { - d->table->dense_below = d->table->field_count; + d->table->UPB_PRIVATE(dense_below) = d->table->UPB_PRIVATE(field_count); need_dense_below = false; } uint32_t skip; @@ -6471,7 +6841,7 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, } if (need_dense_below) { - d->table->dense_below = d->table->field_count; + d->table->UPB_PRIVATE(dense_below) = d->table->UPB_PRIVATE(field_count); } return ptr; @@ -6485,14 +6855,14 @@ static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data, upb_MdDecoder_CheckOutOfMemory(&d->base, d->fields); upb_SubCounts sub_counts = {0, 0}; - d->table->field_count = 0; - d->table->fields = d->fields; + d->table->UPB_PRIVATE(field_count) = 0; + d->table->UPB_PRIVATE(fields) = d->fields; upb_MtDecoder_Parse(d, data, len, d->fields, sizeof(*d->fields), - &d->table->field_count, &sub_counts); + &d->table->UPB_PRIVATE(field_count), &sub_counts); upb_Arena_ShrinkLast(d->arena, d->fields, sizeof(*d->fields) * len, - sizeof(*d->fields) * d->table->field_count); - d->table->fields = d->fields; + sizeof(*d->fields) * d->table->UPB_PRIVATE(field_count)); + d->table->UPB_PRIVATE(fields) = d->fields; upb_MtDecoder_AllocateSubs(d, sub_counts); } @@ -6512,19 +6882,19 @@ int upb_MtDecoder_CompareFields(const void* _a, const void* _b) { #define UPB_COMBINE(rep, ty, idx) (((rep << type_bits) | ty) << idx_bits) | idx uint32_t a_packed = UPB_COMBINE(a->rep, a->type, a->field_index); uint32_t b_packed = UPB_COMBINE(b->rep, b->type, b->field_index); - assert(a_packed != b_packed); + UPB_ASSERT(a_packed != b_packed); #undef UPB_COMBINE return a_packed < b_packed ? -1 : 1; } static bool upb_MtDecoder_SortLayoutItems(upb_MtDecoder* d) { // Add items for all non-oneof fields (oneofs were already added). - int n = d->table->field_count; + int n = d->table->UPB_PRIVATE(field_count); for (int i = 0; i < n; i++) { upb_MiniTableField* f = &d->fields[i]; if (f->offset >= kOneofBase) continue; upb_LayoutItem item = {.field_index = i, - .rep = f->mode >> kUpb_FieldRep_Shift, + .rep = f->UPB_PRIVATE(mode) >> kUpb_FieldRep_Shift, .type = kUpb_LayoutItemType_Field}; upb_MtDecoder_PushItem(d, item); } @@ -6543,46 +6913,49 @@ static size_t upb_MiniTable_DivideRoundUp(size_t n, size_t d) { static void upb_MtDecoder_AssignHasbits(upb_MtDecoder* d) { upb_MiniTable* ret = d->table; - int n = ret->field_count; + int n = ret->UPB_PRIVATE(field_count); int last_hasbit = 0; // 0 cannot be used. // First assign required fields, which must have the lowest hasbits. for (int i = 0; i < n; i++) { - upb_MiniTableField* field = (upb_MiniTableField*)&ret->fields[i]; + upb_MiniTableField* field = + (upb_MiniTableField*)&ret->UPB_PRIVATE(fields)[i]; if (field->offset == kRequiredPresence) { field->presence = ++last_hasbit; } else if (field->offset == kNoPresence) { field->presence = 0; } } - ret->required_count = last_hasbit; - - if (ret->required_count > 63) { + if (last_hasbit > 63) { upb_MdDecoder_ErrorJmp(&d->base, "Too many required fields"); } + ret->UPB_PRIVATE(required_count) = last_hasbit; + // Next assign non-required hasbit fields. for (int i = 0; i < n; i++) { - upb_MiniTableField* field = (upb_MiniTableField*)&ret->fields[i]; + upb_MiniTableField* field = + (upb_MiniTableField*)&ret->UPB_PRIVATE(fields)[i]; if (field->offset == kHasbitPresence) { field->presence = ++last_hasbit; } } - ret->size = last_hasbit ? upb_MiniTable_DivideRoundUp(last_hasbit + 1, 8) : 0; + ret->UPB_PRIVATE(size) = + last_hasbit ? upb_MiniTable_DivideRoundUp(last_hasbit + 1, 8) : 0; } size_t upb_MtDecoder_Place(upb_MtDecoder* d, upb_FieldRep rep) { size_t size = upb_MtDecoder_SizeOfRep(rep, d->platform); size_t align = upb_MtDecoder_AlignOfRep(rep, d->platform); - size_t ret = UPB_ALIGN_UP(d->table->size, align); + size_t ret = UPB_ALIGN_UP(d->table->UPB_PRIVATE(size), align); static const size_t max = UINT16_MAX; size_t new_size = ret + size; if (new_size > max) { upb_MdDecoder_ErrorJmp( &d->base, "Message size exceeded maximum size of %zu bytes", max); } - d->table->size = new_size; + d->table->UPB_PRIVATE(size) = new_size; return ret; } @@ -6602,7 +6975,7 @@ static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) { while (true) { f->presence = ~item->offset; if (f->offset == kUpb_LayoutItem_IndexSentinel) break; - UPB_ASSERT(f->offset - kOneofBase < d->table->field_count); + UPB_ASSERT(f->offset - kOneofBase < d->table->UPB_PRIVATE(field_count)); f = &d->fields[f->offset - kOneofBase]; } } @@ -6632,20 +7005,21 @@ static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) { // // On 32-bit we could potentially make this smaller, but there is no // compelling reason to optimize this right now. - d->table->size = UPB_ALIGN_UP(d->table->size, 8); + d->table->UPB_PRIVATE(size) = UPB_ALIGN_UP(d->table->UPB_PRIVATE(size), 8); } static void upb_MtDecoder_ValidateEntryField(upb_MtDecoder* d, const upb_MiniTableField* f, uint32_t expected_num) { const char* name = expected_num == 1 ? "key" : "val"; - if (f->number != expected_num) { + const uint32_t f_number = upb_MiniTableField_Number(f); + if (f_number != expected_num) { upb_MdDecoder_ErrorJmp(&d->base, "map %s did not have expected number (%d vs %d)", - name, expected_num, (int)f->number); + name, expected_num, f_number); } - if (upb_IsRepeatedOrMap(f)) { + if (!upb_MiniTableField_IsScalar(f)) { upb_MdDecoder_ErrorJmp( &d->base, "map %s cannot be repeated or map, or be in oneof", name); } @@ -6670,9 +7044,9 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data, upb_MtDecoder_ParseMessage(d, data, len); upb_MtDecoder_AssignHasbits(d); - if (UPB_UNLIKELY(d->table->field_count != 2)) { + if (UPB_UNLIKELY(d->table->UPB_PRIVATE(field_count) != 2)) { upb_MdDecoder_ErrorJmp(&d->base, "%hu fields in map", - d->table->field_count); + d->table->UPB_PRIVATE(field_count)); UPB_UNREACHABLE(); } @@ -6683,8 +7057,8 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data, } } - upb_MtDecoder_ValidateEntryField(d, &d->table->fields[0], 1); - upb_MtDecoder_ValidateEntryField(d, &d->table->fields[1], 2); + upb_MtDecoder_ValidateEntryField(d, &d->table->UPB_PRIVATE(fields)[0], 1); + upb_MtDecoder_ValidateEntryField(d, &d->table->UPB_PRIVATE(fields)[1], 2); // Map entries have a pre-determined layout, regardless of types. // NOTE: sync with mini_table/message_internal.h. @@ -6692,11 +7066,12 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data, const size_t hasbit_size = 8; d->fields[0].offset = hasbit_size; d->fields[1].offset = hasbit_size + kv_size; - d->table->size = UPB_ALIGN_UP(hasbit_size + kv_size + kv_size, 8); + d->table->UPB_PRIVATE(size) = + UPB_ALIGN_UP(hasbit_size + kv_size + kv_size, 8); // Map entries have a special bit set to signal it's a map entry, used in // upb_MiniTable_SetSubMessage() below. - d->table->ext |= kUpb_ExtMode_IsMapEntry; + d->table->UPB_PRIVATE(ext) |= kUpb_ExtMode_IsMapEntry; } static void upb_MtDecoder_ParseMessageSet(upb_MtDecoder* d, const char* data, @@ -6707,12 +7082,12 @@ static void upb_MtDecoder_ParseMessageSet(upb_MtDecoder* d, const char* data, } upb_MiniTable* ret = d->table; - ret->size = 0; - ret->field_count = 0; - ret->ext = kUpb_ExtMode_IsMessageSet; - ret->dense_below = 0; - ret->table_mask = -1; - ret->required_count = 0; + ret->UPB_PRIVATE(size) = 0; + ret->UPB_PRIVATE(field_count) = 0; + ret->UPB_PRIVATE(ext) = kUpb_ExtMode_IsMessageSet; + ret->UPB_PRIVATE(dense_below) = 0; + ret->UPB_PRIVATE(table_mask) = -1; + ret->UPB_PRIVATE(required_count) = 0; } static upb_MiniTable* upb_MtDecoder_DoBuildMiniTableWithBuf( @@ -6720,12 +7095,12 @@ static upb_MiniTable* upb_MtDecoder_DoBuildMiniTableWithBuf( size_t* buf_size) { upb_MdDecoder_CheckOutOfMemory(&decoder->base, decoder->table); - decoder->table->size = 0; - decoder->table->field_count = 0; - decoder->table->ext = kUpb_ExtMode_NonExtendable; - decoder->table->dense_below = 0; - decoder->table->table_mask = -1; - decoder->table->required_count = 0; + decoder->table->UPB_PRIVATE(size) = 0; + decoder->table->UPB_PRIVATE(field_count) = 0; + decoder->table->UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable; + decoder->table->UPB_PRIVATE(dense_below) = 0; + decoder->table->UPB_PRIVATE(table_mask) = -1; + decoder->table->UPB_PRIVATE(required_count) = 0; // Strip off and verify the version tag. if (!len--) goto done; @@ -6812,22 +7187,22 @@ static const char* upb_MtDecoder_DoBuildMiniTableExtension( &count, &sub_counts); if (!ret || count != 1) return NULL; - upb_MiniTableField* f = &ext->field; + upb_MiniTableField* f = &ext->UPB_PRIVATE(field); - f->mode |= kUpb_LabelFlags_IsExtension; + f->UPB_PRIVATE(mode) |= kUpb_LabelFlags_IsExtension; f->offset = 0; f->presence = 0; - if (extendee->ext & kUpb_ExtMode_IsMessageSet) { + if (extendee->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMessageSet) { // Extensions of MessageSet must be messages. - if (!upb_IsSubMessage(f)) return NULL; + if (!upb_MiniTableField_IsSubMessage(f)) return NULL; // Extensions of MessageSet must be non-repeating. - if ((f->mode & kUpb_FieldMode_Mask) == kUpb_FieldMode_Array) return NULL; + if (upb_MiniTableField_IsArray(f)) return NULL; } - ext->extendee = extendee; - ext->sub = sub; + ext->UPB_PRIVATE(extendee) = extendee; + ext->UPB_PRIVATE(sub) = sub; return ret; } @@ -6885,25 +7260,32 @@ upb_MiniTable* _upb_MiniTable_Build(const char* data, size_t len, } +#include +#include + + // Must be last. bool upb_MiniTable_SetSubMessage(upb_MiniTable* table, upb_MiniTableField* field, const upb_MiniTable* sub) { - UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field && - (uintptr_t)field < - (uintptr_t)(table->fields + table->field_count)); + UPB_ASSERT((uintptr_t)table->UPB_PRIVATE(fields) <= (uintptr_t)field && + (uintptr_t)field < (uintptr_t)(table->UPB_PRIVATE(fields) + + table->UPB_PRIVATE(field_count))); UPB_ASSERT(sub); - const bool sub_is_map = sub->ext & kUpb_ExtMode_IsMapEntry; + const bool sub_is_map = sub->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry; switch (field->UPB_PRIVATE(descriptortype)) { case kUpb_FieldType_Message: if (sub_is_map) { - const bool table_is_map = table->ext & kUpb_ExtMode_IsMapEntry; + const bool table_is_map = + table->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry; if (UPB_UNLIKELY(table_is_map)) return false; - field->mode = (field->mode & ~kUpb_FieldMode_Mask) | kUpb_FieldMode_Map; + field->UPB_PRIVATE(mode) = + (field->UPB_PRIVATE(mode) & ~kUpb_FieldMode_Mask) | + kUpb_FieldMode_Map; } break; @@ -6916,24 +7298,24 @@ bool upb_MiniTable_SetSubMessage(upb_MiniTable* table, } upb_MiniTableSub* table_sub = - (void*)&table->subs[field->UPB_PRIVATE(submsg_index)]; + (void*)&table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]; // TODO: Add this assert back once YouTube is updated to not call // this function repeatedly. - // UPB_ASSERT(table_sub->submsg == &_kUpb_MiniTable_Empty); - table_sub->submsg = sub; + // UPB_ASSERT(UPB_PRIVATE(_upb_MiniTable_IsEmpty)(table_sub->submsg)); + *table_sub = upb_MiniTableSub_FromMessage(sub); return true; } bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field, const upb_MiniTableEnum* sub) { - UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field && - (uintptr_t)field < - (uintptr_t)(table->fields + table->field_count)); + UPB_ASSERT((uintptr_t)table->UPB_PRIVATE(fields) <= (uintptr_t)field && + (uintptr_t)field < (uintptr_t)(table->UPB_PRIVATE(fields) + + table->UPB_PRIVATE(field_count))); UPB_ASSERT(sub); upb_MiniTableSub* table_sub = - (void*)&table->subs[field->UPB_PRIVATE(submsg_index)]; - table_sub->subenum = sub; + (void*)&table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]; + *table_sub = upb_MiniTableSub_FromEnum(sub); return true; } @@ -6942,8 +7324,8 @@ uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt, uint32_t msg_count = 0; uint32_t enum_count = 0; - for (int i = 0; i < mt->field_count; i++) { - const upb_MiniTableField* f = &mt->fields[i]; + for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) { + const upb_MiniTableField* f = &mt->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_CType(f) == kUpb_CType_Message) { *subs = f; ++subs; @@ -6951,8 +7333,8 @@ uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt, } } - for (int i = 0; i < mt->field_count; i++) { - const upb_MiniTableField* f = &mt->fields[i]; + for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) { + const upb_MiniTableField* f = &mt->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_CType(f) == kUpb_CType_Enum) { *subs = f; ++subs; @@ -6973,8 +7355,8 @@ bool upb_MiniTable_Link(upb_MiniTable* mt, const upb_MiniTable** sub_tables, uint32_t msg_count = 0; uint32_t enum_count = 0; - for (int i = 0; i < mt->field_count; i++) { - upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i]; + for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) { + upb_MiniTableField* f = (upb_MiniTableField*)&mt->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_CType(f) == kUpb_CType_Message) { const upb_MiniTable* sub = sub_tables[msg_count++]; if (msg_count > sub_table_count) return false; @@ -6984,8 +7366,8 @@ bool upb_MiniTable_Link(upb_MiniTable* mt, const upb_MiniTable** sub_tables, } } - for (int i = 0; i < mt->field_count; i++) { - upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i]; + for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) { + upb_MiniTableField* f = (upb_MiniTableField*)&mt->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_IsClosedEnum(f)) { const upb_MiniTableEnum* sub = sub_enums[enum_count++]; if (enum_count > sub_enum_count) return false; @@ -7329,6 +7711,10 @@ char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr) { } +#include +#include +#include + // Must be last. @@ -7355,7 +7741,7 @@ upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena) { UPB_API bool upb_ExtensionRegistry_Add(upb_ExtensionRegistry* r, const upb_MiniTableExtension* e) { char buf[EXTREG_KEY_SIZE]; - extreg_key(buf, e->extendee, e->field.number); + extreg_key(buf, e->UPB_PRIVATE(extendee), upb_MiniTableExtension_Number(e)); if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, NULL)) return false; return upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE, upb_value_constptr(e), r->arena); @@ -7376,7 +7762,8 @@ failure: for (end = e, e = start; e < end; e++) { const upb_MiniTableExtension* ext = *e; char buf[EXTREG_KEY_SIZE]; - extreg_key(buf, ext->extendee, ext->field.number); + extreg_key(buf, ext->UPB_PRIVATE(extendee), + upb_MiniTableExtension_Number(ext)); upb_strtable_remove2(&r->exts, buf, EXTREG_KEY_SIZE, NULL); } return false; @@ -7396,26 +7783,28 @@ const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup( #include +#include +#include // Must be last. const upb_MiniTableField* upb_MiniTable_FindFieldByNumber( - const upb_MiniTable* t, uint32_t number) { + const upb_MiniTable* m, uint32_t number) { const size_t i = ((size_t)number) - 1; // 0 wraps to SIZE_MAX // Ideal case: index into dense fields - if (i < t->dense_below) { - UPB_ASSERT(t->fields[i].number == number); - return &t->fields[i]; + if (i < m->UPB_PRIVATE(dense_below)) { + UPB_ASSERT(m->UPB_PRIVATE(fields)[i].UPB_PRIVATE(number) == number); + return &m->UPB_PRIVATE(fields)[i]; } // Slow case: binary search - int lo = t->dense_below; - int hi = t->field_count - 1; + int lo = m->UPB_PRIVATE(dense_below); + int hi = m->UPB_PRIVATE(field_count) - 1; while (lo <= hi) { int mid = (lo + hi) / 2; - uint32_t num = t->fields[mid].number; + uint32_t num = m->UPB_PRIVATE(fields)[mid].UPB_PRIVATE(number); if (num < number) { lo = mid + 1; continue; @@ -7424,23 +7813,20 @@ const upb_MiniTableField* upb_MiniTable_FindFieldByNumber( hi = mid - 1; continue; } - return &t->fields[mid]; + return &m->UPB_PRIVATE(fields)[mid]; } return NULL; } -static bool upb_MiniTable_Is_Oneof(const upb_MiniTableField* f) { - return f->presence < 0; -} - const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, const upb_MiniTableField* f) { - if (UPB_UNLIKELY(!upb_MiniTable_Is_Oneof(f))) { + if (UPB_UNLIKELY(!upb_MiniTableField_IsInOneof(f))) { return NULL; } - const upb_MiniTableField* ptr = &m->fields[0]; - const upb_MiniTableField* end = &m->fields[m->field_count]; - while (++ptr < end) { + const upb_MiniTableField* ptr = &m->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* end = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; + for (; ptr < end; ptr++) { if (ptr->presence == (*f).presence) { return ptr; } @@ -7451,7 +7837,8 @@ const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, const upb_MiniTableField** f) { const upb_MiniTableField* ptr = *f; - const upb_MiniTableField* end = &m->fields[m->field_count]; + const upb_MiniTableField* end = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; while (++ptr < end) { if (ptr->presence == (*f)->presence) { *f = ptr; @@ -7462,15 +7849,20 @@ bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, } -const struct upb_MiniTable _kUpb_MiniTable_Empty = { - .subs = NULL, - .fields = NULL, - .size = 0, - .field_count = 0, - .ext = kUpb_ExtMode_NonExtendable, - .dense_below = 0, - .table_mask = -1, - .required_count = 0, +#include + +// Must be last. + +// A MiniTable for an empty message, used for unlinked sub-messages. +const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty) = { + .UPB_PRIVATE(subs) = NULL, + .UPB_PRIVATE(fields) = NULL, + .UPB_PRIVATE(size) = 0, + .UPB_PRIVATE(field_count) = 0, + .UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable, + .UPB_PRIVATE(dense_below) = 0, + .UPB_PRIVATE(table_mask) = -1, + .UPB_PRIVATE(required_count) = 0, }; @@ -7483,6 +7875,7 @@ struct upb_DefPool { upb_strtable files; // file_name -> (upb_FileDef*) upb_inttable exts; // (upb_MiniTableExtension*) -> (upb_FieldDef*) upb_ExtensionRegistry* extreg; + const UPB_DESC(FeatureSetDefaults) * feature_set_defaults; upb_MiniTablePlatform platform; void* scratch_data; size_t scratch_size; @@ -7495,6 +7888,8 @@ void upb_DefPool_Free(upb_DefPool* s) { upb_gfree(s); } +static const char serialized_defaults[] = UPB_INTERNAL_UPB_EDITION_DEFAULTS; + upb_DefPool* upb_DefPool_New(void) { upb_DefPool* s = upb_gmalloc(sizeof(*s)); if (!s) return NULL; @@ -7515,6 +7910,14 @@ upb_DefPool* upb_DefPool_New(void) { s->platform = kUpb_MiniTablePlatform_Native; + upb_Status status; + if (!upb_DefPool_SetFeatureSetDefaults( + s, serialized_defaults, sizeof(serialized_defaults) - 1, &status)) { + goto err; + } + + if (!s->feature_set_defaults) goto err; + return s; err: @@ -7522,6 +7925,63 @@ err: return NULL; } +const UPB_DESC(FeatureSetDefaults) * + upb_DefPool_FeatureSetDefaults(const upb_DefPool* s) { + return s->feature_set_defaults; +} + +bool upb_DefPool_SetFeatureSetDefaults(upb_DefPool* s, + const char* serialized_defaults, + size_t serialized_len, + upb_Status* status) { + const UPB_DESC(FeatureSetDefaults)* defaults = UPB_DESC( + FeatureSetDefaults_parse)(serialized_defaults, serialized_len, s->arena); + if (!defaults) { + upb_Status_SetErrorFormat(status, "Failed to parse defaults"); + return false; + } + if (upb_strtable_count(&s->files) > 0) { + upb_Status_SetErrorFormat(status, + "Feature set defaults can't be changed once the " + "pool has started building"); + return false; + } + int min_edition = UPB_DESC(FeatureSetDefaults_minimum_edition(defaults)); + int max_edition = UPB_DESC(FeatureSetDefaults_maximum_edition(defaults)); + if (min_edition > max_edition) { + upb_Status_SetErrorFormat(status, "Invalid edition range %s to %s", + upb_FileDef_EditionName(min_edition), + upb_FileDef_EditionName(max_edition)); + return false; + } + size_t size; + const UPB_DESC( + FeatureSetDefaults_FeatureSetEditionDefault)* const* default_list = + UPB_DESC(FeatureSetDefaults_defaults(defaults, &size)); + int prev_edition = UPB_DESC(EDITION_UNKNOWN); + for (size_t i = 0; i < size; ++i) { + int edition = UPB_DESC( + FeatureSetDefaults_FeatureSetEditionDefault_edition(default_list[i])); + if (edition == UPB_DESC(EDITION_UNKNOWN)) { + upb_Status_SetErrorFormat(status, "Invalid edition UNKNOWN specified"); + return false; + } + if (edition <= prev_edition) { + upb_Status_SetErrorFormat(status, + "Feature set defaults are not strictly " + "increasing, %s is greater than or equal to %s", + upb_FileDef_EditionName(prev_edition), + upb_FileDef_EditionName(edition)); + return false; + } + prev_edition = edition; + } + + // Copy the defaults into the pool. + s->feature_set_defaults = defaults; + return true; +} + bool _upb_DefPool_InsertExt(upb_DefPool* s, const upb_MiniTableExtension* ext, const upb_FieldDef* f) { return upb_inttable_insert(&s->exts, (uintptr_t)ext, upb_value_constptr(f), @@ -7735,7 +8195,11 @@ static const upb_FileDef* upb_DefBuilder_AddFileToPool( remove_filedef(s, builder->file); builder->file = NULL; } - } else if (!builder->arena || !builder->tmp_arena) { + } else if (!builder->arena || !builder->tmp_arena || + !upb_strtable_init(&builder->feature_cache, 16, + builder->tmp_arena) || + !(builder->legacy_features = + UPB_DESC(FeatureSet_new)(builder->tmp_arena))) { _upb_DefBuilder_OomErr(builder); } else { _upb_FileDef_Create(builder, file_proto); @@ -7768,6 +8232,8 @@ static const upb_FileDef* _upb_DefPool_AddFile( upb_DefBuilder ctx = { .symtab = s, + .tmp_buf = NULL, + .tmp_buf_size = 0, .layout = layout, .platform = s->platform, .msg_count = 0, @@ -7883,7 +8349,7 @@ const upb_FieldDef** upb_DefPool_GetAllExtensions(const upb_DefPool* s, const upb_FieldDef* f = upb_value_getconstptr(val); if (upb_FieldDef_ContainingType(f) == m) n++; } - const upb_FieldDef** exts = malloc(n * sizeof(*exts)); + const upb_FieldDef** exts = upb_gmalloc(n * sizeof(*exts)); iter = UPB_INTTABLE_BEGIN; size_t i = 0; while (upb_inttable_next(&s->exts, &key, &val, &iter)) { @@ -7946,11 +8412,16 @@ bool _upb_DescState_Grow(upb_DescState* d, upb_Arena* a) { } +#include +#include +#include + // Must be last. struct upb_EnumDef { - const UPB_DESC(EnumOptions) * opts; + const UPB_DESC(EnumOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; const upb_MiniTableEnum* layout; // Only for proto2. const upb_FileDef* file; const upb_MessageDef* containing_type; // Could be merged with "file". @@ -7964,8 +8435,10 @@ struct upb_EnumDef { int res_range_count; int res_name_count; int32_t defaultval; - bool is_closed; bool is_sorted; // Whether all of the values are defined in ascending order. +#if UINTPTR_MAX == 0xffffffff + uint32_t padding; // Increase size to a multiple of 8. +#endif }; upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i) { @@ -7998,6 +8471,11 @@ bool upb_EnumDef_HasOptions(const upb_EnumDef* e) { return e->opts != (void*)kUpbDefOptDefault; } +const UPB_DESC(FeatureSet) * + upb_EnumDef_ResolvedFeatures(const upb_EnumDef* e) { + return e->resolved_features; +} + const char* upb_EnumDef_FullName(const upb_EnumDef* e) { return e->full_name; } const char* upb_EnumDef_Name(const upb_EnumDef* e) { @@ -8067,7 +8545,11 @@ const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i) { return _upb_EnumValueDef_At(e->values, i); } -bool upb_EnumDef_IsClosed(const upb_EnumDef* e) { return e->is_closed; } +bool upb_EnumDef_IsClosed(const upb_EnumDef* e) { + if (UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3) return false; + return UPB_DESC(FeatureSet_enum_type)(e->resolved_features) == + UPB_DESC(FeatureSet_CLOSED); +} bool upb_EnumDef_MiniDescriptorEncode(const upb_EnumDef* e, upb_Arena* a, upb_StringView* out) { @@ -8136,6 +8618,7 @@ static upb_StringView* _upb_EnumReservedNames_New( static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, const UPB_DESC(EnumDescriptorProto) * enum_proto, + const UPB_DESC(FeatureSet*) parent_features, upb_EnumDef* e) { const UPB_DESC(EnumValueDescriptorProto)* const* values; const UPB_DESC(EnumDescriptorProto_EnumReservedRange)* const* res_ranges; @@ -8143,6 +8626,10 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, upb_StringView name; size_t n_value, n_res_range, n_res_name; + UPB_DEF_SET_OPTIONS(e->opts, EnumDescriptorProto, EnumOptions, enum_proto); + e->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, UPB_DESC(EnumOptions_features)(e->opts)); + // Must happen before _upb_DefBuilder_Add() e->file = _upb_DefBuilder_File(ctx); @@ -8152,9 +8639,6 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, _upb_DefBuilder_Add(ctx, e->full_name, _upb_DefType_Pack(e, UPB_DEFTYPE_ENUM)); - e->is_closed = (!UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3) && - (upb_FileDef_Syntax(e->file) == kUpb_Syntax_Proto2); - values = UPB_DESC(EnumDescriptorProto_value)(enum_proto, &n_value); bool ok = upb_strtable_init(&e->ntoi, n_value, ctx->arena); @@ -8165,8 +8649,8 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, e->defaultval = 0; e->value_count = n_value; - e->values = - _upb_EnumValueDefs_New(ctx, prefix, n_value, values, e, &e->is_sorted); + e->values = _upb_EnumValueDefs_New(ctx, prefix, n_value, values, + e->resolved_features, e, &e->is_sorted); if (n_value == 0) { _upb_DefBuilder_Errf(ctx, "enums must contain at least one value (%s)", @@ -8183,14 +8667,11 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, e->res_name_count = n_res_name; e->res_names = _upb_EnumReservedNames_New(ctx, n_res_name, res_names); - UPB_DEF_SET_OPTIONS(e->opts, EnumDescriptorProto, EnumOptions, enum_proto); - upb_inttable_compact(&e->iton, ctx->arena); - if (e->is_closed) { + if (upb_EnumDef_IsClosed(e)) { if (ctx->layout) { - UPB_ASSERT(ctx->enum_count < ctx->layout->enum_count); - e->layout = ctx->layout->enums[ctx->enum_count++]; + e->layout = upb_MiniTableFile_Enum(ctx->layout, ctx->enum_count++); } else { e->layout = create_enumlayout(ctx, e); } @@ -8199,10 +8680,11 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, } } -upb_EnumDef* _upb_EnumDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(EnumDescriptorProto) * const* protos, - const upb_MessageDef* containing_type) { +upb_EnumDef* _upb_EnumDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(EnumDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + const upb_MessageDef* containing_type) { _upb_DefType_CheckPadding(sizeof(upb_EnumDef)); // If a containing type is defined then get the full name from that. @@ -8212,7 +8694,7 @@ upb_EnumDef* _upb_EnumDefs_New( upb_EnumDef* e = _upb_DefBuilder_Alloc(ctx, sizeof(upb_EnumDef) * n); for (int i = 0; i < n; i++) { - create_enumdef(ctx, name, protos[i], &e[i]); + create_enumdef(ctx, name, protos[i], parent_features, &e[i]); e[i].containing_type = containing_type; } return e; @@ -8271,14 +8753,20 @@ upb_EnumReservedRange* _upb_EnumReservedRanges_New( } +#include + // Must be last. struct upb_EnumValueDef { - const UPB_DESC(EnumValueOptions) * opts; + const UPB_DESC(EnumValueOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; const upb_EnumDef* parent; const char* full_name; int32_t number; +#if UINTPTR_MAX == 0xffffffff + uint32_t padding; // Increase size to a multiple of 8. +#endif }; upb_EnumValueDef* _upb_EnumValueDef_At(const upb_EnumValueDef* v, int i) { @@ -8315,6 +8803,11 @@ bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* v) { return v->opts != (void*)kUpbDefOptDefault; } +const UPB_DESC(FeatureSet) * + upb_EnumValueDef_ResolvedFeatures(const upb_EnumValueDef* e) { + return e->resolved_features; +} + const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* v) { return v->parent; } @@ -8335,9 +8828,15 @@ uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v) { } static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix, - const UPB_DESC(EnumValueDescriptorProto) * + const UPB_DESC(EnumValueDescriptorProto*) val_proto, + const UPB_DESC(FeatureSet*) parent_features, upb_EnumDef* e, upb_EnumValueDef* v) { + UPB_DEF_SET_OPTIONS(v->opts, EnumValueDescriptorProto, EnumValueOptions, + val_proto); + v->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, UPB_DESC(EnumValueOptions_features)(v->opts)); + upb_StringView name = UPB_DESC(EnumValueDescriptorProto_name)(val_proto); v->parent = e; // Must happen prior to _upb_DefBuilder_Add() @@ -8346,17 +8845,32 @@ static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix, _upb_DefBuilder_Add(ctx, v->full_name, _upb_DefType_Pack(v, UPB_DEFTYPE_ENUMVAL)); - UPB_DEF_SET_OPTIONS(v->opts, EnumValueDescriptorProto, EnumValueOptions, - val_proto); - bool ok = _upb_EnumDef_Insert(e, v, ctx->arena); if (!ok) _upb_DefBuilder_OomErr(ctx); } +static void _upb_EnumValueDef_CheckZeroValue(upb_DefBuilder* ctx, + const upb_EnumDef* e, + const upb_EnumValueDef* v, int n) { + if (upb_EnumDef_IsClosed(e) || n == 0 || v[0].number == 0) return; + + // When the special UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 is enabled, we have to + // exempt proto2 enums from this check, even when we are treating them as + // open. + if (UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3 && + upb_FileDef_Syntax(upb_EnumDef_File(e)) == kUpb_Syntax_Proto2) { + return; + } + + _upb_DefBuilder_Errf(ctx, "for open enums, the first value must be zero (%s)", + upb_EnumDef_FullName(e)); +} + // Allocate and initialize an array of |n| enum value defs owned by |e|. upb_EnumValueDef* _upb_EnumValueDefs_New( upb_DefBuilder* ctx, const char* prefix, int n, - const UPB_DESC(EnumValueDescriptorProto) * const* protos, upb_EnumDef* e, + const UPB_DESC(EnumValueDescriptorProto*) const* protos, + const UPB_DESC(FeatureSet*) parent_features, upb_EnumDef* e, bool* is_sorted) { _upb_DefType_CheckPadding(sizeof(upb_EnumValueDef)); @@ -8366,29 +8880,27 @@ upb_EnumValueDef* _upb_EnumValueDefs_New( *is_sorted = true; uint32_t previous = 0; for (int i = 0; i < n; i++) { - create_enumvaldef(ctx, prefix, protos[i], e, &v[i]); + create_enumvaldef(ctx, prefix, protos[i], parent_features, e, &v[i]); const uint32_t current = v[i].number; if (previous > current) *is_sorted = false; previous = current; } - if (upb_FileDef_Syntax(ctx->file) == kUpb_Syntax_Proto3 && n > 0 && - v[0].number != 0) { - _upb_DefBuilder_Errf(ctx, - "for proto3, the first enum value must be zero (%s)", - upb_EnumDef_FullName(e)); - } + _upb_EnumValueDef_CheckZeroValue(ctx, e, v, n); return v; } +#include + // Must be last. struct upb_ExtensionRange { - const UPB_DESC(ExtensionRangeOptions) * opts; + const UPB_DESC(ExtensionRangeOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; int32_t start; int32_t end; }; @@ -8414,12 +8926,18 @@ int32_t upb_ExtensionRange_End(const upb_ExtensionRange* r) { return r->end; } upb_ExtensionRange* _upb_ExtensionRanges_New( upb_DefBuilder* ctx, int n, - const UPB_DESC(DescriptorProto_ExtensionRange) * const* protos, - const upb_MessageDef* m) { + const UPB_DESC(DescriptorProto_ExtensionRange*) const* protos, + const UPB_DESC(FeatureSet*) parent_features, const upb_MessageDef* m) { upb_ExtensionRange* r = _upb_DefBuilder_Alloc(ctx, sizeof(upb_ExtensionRange) * n); for (int i = 0; i < n; i++) { + UPB_DEF_SET_OPTIONS(r[i].opts, DescriptorProto_ExtensionRange, + ExtensionRangeOptions, protos[i]); + r[i].resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, + UPB_DESC(ExtensionRangeOptions_features)(r[i].opts)); + const int32_t start = UPB_DESC(DescriptorProto_ExtensionRange_start)(protos[i]); const int32_t end = UPB_DESC(DescriptorProto_ExtensionRange_end)(protos[i]); @@ -8439,8 +8957,6 @@ upb_ExtensionRange* _upb_ExtensionRanges_New( r[i].start = start; r[i].end = end; - UPB_DEF_SET_OPTIONS(r[i].opts, DescriptorProto_ExtensionRange, - ExtensionRangeOptions, protos[i]); } return r; @@ -8450,6 +8966,9 @@ upb_ExtensionRange* _upb_ExtensionRanges_New( #include #include #include +#include +#include +#include // Must be last. @@ -8462,7 +8981,8 @@ typedef struct { } str_t; struct upb_FieldDef { - const UPB_DESC(FieldOptions) * opts; + const UPB_DESC(FieldOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; const upb_FileDef* file; const upb_MessageDef* msgdef; const char* full_name; @@ -8492,13 +9012,9 @@ struct upb_FieldDef { bool has_json_name; bool has_presence; bool is_extension; - bool is_packed; bool is_proto3_optional; upb_FieldType type_; upb_Label label_; -#if UINTPTR_MAX == 0xffffffff - uint32_t padding; // Increase size to a multiple of 8. -#endif }; upb_FieldDef* _upb_FieldDef_At(const upb_FieldDef* f, int i) { @@ -8513,50 +9029,39 @@ bool upb_FieldDef_HasOptions(const upb_FieldDef* f) { return f->opts != (void*)kUpbDefOptDefault; } +const UPB_DESC(FeatureSet) * + upb_FieldDef_ResolvedFeatures(const upb_FieldDef* f) { + return f->resolved_features; +} + const char* upb_FieldDef_FullName(const upb_FieldDef* f) { return f->full_name; } upb_CType upb_FieldDef_CType(const upb_FieldDef* f) { - switch (f->type_) { - case kUpb_FieldType_Double: - return kUpb_CType_Double; - case kUpb_FieldType_Float: - return kUpb_CType_Float; - case kUpb_FieldType_Int64: - case kUpb_FieldType_SInt64: - case kUpb_FieldType_SFixed64: - return kUpb_CType_Int64; - case kUpb_FieldType_Int32: - case kUpb_FieldType_SFixed32: - case kUpb_FieldType_SInt32: - return kUpb_CType_Int32; - case kUpb_FieldType_UInt64: - case kUpb_FieldType_Fixed64: - return kUpb_CType_UInt64; - case kUpb_FieldType_UInt32: - case kUpb_FieldType_Fixed32: - return kUpb_CType_UInt32; - case kUpb_FieldType_Enum: - return kUpb_CType_Enum; - case kUpb_FieldType_Bool: - return kUpb_CType_Bool; - case kUpb_FieldType_String: - return kUpb_CType_String; - case kUpb_FieldType_Bytes: - return kUpb_CType_Bytes; - case kUpb_FieldType_Group: - case kUpb_FieldType_Message: - return kUpb_CType_Message; - } - UPB_UNREACHABLE(); + return upb_FieldType_CType(f->type_); } -upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f) { return f->type_; } +upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f) { + // TODO: remove once we can deprecate kUpb_FieldType_Group. + if (f->type_ == kUpb_FieldType_Message && + UPB_DESC(FeatureSet_message_encoding)(f->resolved_features) == + UPB_DESC(FeatureSet_DELIMITED)) { + return kUpb_FieldType_Group; + } + return f->type_; +} uint32_t upb_FieldDef_Index(const upb_FieldDef* f) { return f->index_; } -upb_Label upb_FieldDef_Label(const upb_FieldDef* f) { return f->label_; } +upb_Label upb_FieldDef_Label(const upb_FieldDef* f) { + // TODO: remove once we can deprecate kUpb_Label_Required. + if (UPB_DESC(FeatureSet_field_presence)(f->resolved_features) == + UPB_DESC(FeatureSet_LEGACY_REQUIRED)) { + return kUpb_Label_Required; + } + return f->label_; +} uint32_t upb_FieldDef_Number(const upb_FieldDef* f) { return f->number_; } @@ -8567,7 +9072,9 @@ bool _upb_FieldDef_IsPackable(const upb_FieldDef* f) { } bool upb_FieldDef_IsPacked(const upb_FieldDef* f) { - return _upb_FieldDef_IsPackable(f) && f->is_packed; + return _upb_FieldDef_IsPackable(f) && + UPB_DESC(FeatureSet_repeated_field_encoding(f->resolved_features)) == + UPB_DESC(FeatureSet_PACKED); } const char* upb_FieldDef_Name(const upb_FieldDef* f) { @@ -8658,7 +9165,7 @@ const upb_MiniTableField* upb_FieldDef_MiniTable(const upb_FieldDef* f) { file, f->layout_index); } else { const upb_MiniTable* layout = upb_MessageDef_MiniTable(f->msgdef); - return &layout->fields[f->layout_index]; + return &layout->UPB_PRIVATE(fields)[f->layout_index]; } } @@ -8680,44 +9187,21 @@ bool _upb_FieldDef_IsProto3Optional(const upb_FieldDef* f) { int _upb_FieldDef_LayoutIndex(const upb_FieldDef* f) { return f->layout_index; } -// begin:google_only -// static bool _upb_FieldDef_EnforceUtf8Option(const upb_FieldDef* f) { -// #if defined(UPB_BOOTSTRAP_STAGE0) -// return true; -// #else -// return UPB_DESC(FieldOptions_enforce_utf8)(f->opts); -// #endif -// } -// end:google_only - -// begin:github_only -static bool _upb_FieldDef_EnforceUtf8Option(const upb_FieldDef* f) { - return true; -} -// end:github_only - bool _upb_FieldDef_ValidateUtf8(const upb_FieldDef* f) { if (upb_FieldDef_Type(f) != kUpb_FieldType_String) return false; - return upb_FileDef_Syntax(upb_FieldDef_File(f)) == kUpb_Syntax_Proto3 - ? _upb_FieldDef_EnforceUtf8Option(f) - : false; + return UPB_DESC(FeatureSet_utf8_validation(f->resolved_features)) == + UPB_DESC(FeatureSet_VERIFY); } uint64_t _upb_FieldDef_Modifiers(const upb_FieldDef* f) { uint64_t out = upb_FieldDef_IsPacked(f) ? kUpb_FieldModifier_IsPacked : 0; - switch (f->label_) { - case kUpb_Label_Optional: - if (!upb_FieldDef_HasPresence(f)) { - out |= kUpb_FieldModifier_IsProto3Singular; - } - break; - case kUpb_Label_Repeated: - out |= kUpb_FieldModifier_IsRepeated; - break; - case kUpb_Label_Required: - out |= kUpb_FieldModifier_IsRequired; - break; + if (upb_FieldDef_IsRepeated(f)) { + out |= kUpb_FieldModifier_IsRepeated; + } else if (upb_FieldDef_IsRequired(f)) { + out |= kUpb_FieldModifier_IsRequired; + } else if (!upb_FieldDef_HasPresence(f)) { + out |= kUpb_FieldModifier_IsProto3Singular; } if (_upb_FieldDef_IsClosedEnum(f)) { @@ -8757,7 +9241,8 @@ bool upb_FieldDef_IsRepeated(const upb_FieldDef* f) { } bool upb_FieldDef_IsRequired(const upb_FieldDef* f) { - return upb_FieldDef_Label(f) == kUpb_Label_Required; + return UPB_DESC(FeatureSet_field_presence)(f->resolved_features) == + UPB_DESC(FeatureSet_LEGACY_REQUIRED); } bool upb_FieldDef_IsString(const upb_FieldDef* f) { @@ -8981,19 +9466,63 @@ static void set_default_default(upb_DefBuilder* ctx, upb_FieldDef* f) { } } +static bool _upb_FieldDef_InferLegacyFeatures( + upb_DefBuilder* ctx, upb_FieldDef* f, + const UPB_DESC(FieldDescriptorProto*) proto, + const UPB_DESC(FieldOptions*) options, upb_Syntax syntax, + UPB_DESC(FeatureSet*) features) { + bool ret = false; + + if (UPB_DESC(FieldDescriptorProto_label)(proto) == kUpb_Label_Required) { + if (syntax == kUpb_Syntax_Proto3) { + _upb_DefBuilder_Errf(ctx, "proto3 fields cannot be required (%s)", + f->full_name); + } + int val = UPB_DESC(FeatureSet_LEGACY_REQUIRED); + UPB_DESC(FeatureSet_set_field_presence(features, val)); + ret = true; + } + + if (UPB_DESC(FieldDescriptorProto_type)(proto) == kUpb_FieldType_Group) { + int val = UPB_DESC(FeatureSet_DELIMITED); + UPB_DESC(FeatureSet_set_message_encoding(features, val)); + ret = true; + } + + if (UPB_DESC(FieldOptions_has_packed)(options)) { + int val = UPB_DESC(FieldOptions_packed)(options) + ? UPB_DESC(FeatureSet_PACKED) + : UPB_DESC(FeatureSet_EXPANDED); + UPB_DESC(FeatureSet_set_repeated_field_encoding(features, val)); + ret = true; + } + +// begin:google_only +// #ifndef UPB_BOOTSTRAP_STAGE0 +// if (syntax == kUpb_Syntax_Proto3 && +// UPB_DESC(FieldOptions_has_enforce_utf8)(options) && +// !UPB_DESC(FieldOptions_enforce_utf8)(options)) { +// int val = UPB_DESC(FeatureSet_UNVERIFIED); +// UPB_DESC(FeatureSet_set_utf8_validation(features, val)); +// ret = true; +// } +// #endif +// // clang-format off +// end:google_only + // clang-format on + + return ret; +} + static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix, - const UPB_DESC(FieldDescriptorProto) * + const UPB_DESC(FeatureSet*) parent_features, + const UPB_DESC(FieldDescriptorProto*) field_proto, upb_MessageDef* m, upb_FieldDef* f) { // Must happen before _upb_DefBuilder_Add() f->file = _upb_DefBuilder_File(ctx); - if (!UPB_DESC(FieldDescriptorProto_has_name)(field_proto)) { - _upb_DefBuilder_Errf(ctx, "field has no name"); - } - const upb_StringView name = UPB_DESC(FieldDescriptorProto_name)(field_proto); - f->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name); f->label_ = (int)UPB_DESC(FieldDescriptorProto_label)(field_proto); f->number_ = UPB_DESC(FieldDescriptorProto_number)(field_proto); @@ -9002,6 +9531,48 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix, f->msgdef = m; f->scope.oneof = NULL; + UPB_DEF_SET_OPTIONS(f->opts, FieldDescriptorProto, FieldOptions, field_proto); + + upb_Syntax syntax = upb_FileDef_Syntax(f->file); + const UPB_DESC(FeatureSet*) unresolved_features = + UPB_DESC(FieldOptions_features)(f->opts); + bool implicit = false; + + if (syntax != kUpb_Syntax_Editions) { + upb_Message_Clear(ctx->legacy_features, UPB_DESC_MINITABLE(FeatureSet)); + if (_upb_FieldDef_InferLegacyFeatures(ctx, f, field_proto, f->opts, syntax, + ctx->legacy_features)) { + implicit = true; + unresolved_features = ctx->legacy_features; + } + } + + if (UPB_DESC(FieldDescriptorProto_has_oneof_index)(field_proto)) { + int oneof_index = UPB_DESC(FieldDescriptorProto_oneof_index)(field_proto); + + if (!m) { + _upb_DefBuilder_Errf(ctx, "oneof field (%s) has no containing msg", + f->full_name); + } + + if (oneof_index >= upb_MessageDef_OneofCount(m)) { + _upb_DefBuilder_Errf(ctx, "oneof_index out of range (%s)", f->full_name); + } + + upb_OneofDef* oneof = (upb_OneofDef*)upb_MessageDef_Oneof(m, oneof_index); + f->scope.oneof = oneof; + parent_features = upb_OneofDef_ResolvedFeatures(oneof); + + _upb_OneofDef_Insert(ctx, oneof, f, name.data, name.size); + } + + f->resolved_features = _upb_DefBuilder_DoResolveFeatures( + ctx, parent_features, unresolved_features, implicit); + + if (!UPB_DESC(FieldDescriptorProto_has_name)(field_proto)) { + _upb_DefBuilder_Errf(ctx, "field has no name"); + } + f->has_json_name = UPB_DESC(FieldDescriptorProto_has_json_name)(field_proto); if (f->has_json_name) { const upb_StringView sv = @@ -9057,56 +9628,28 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix, * to the field_proto until later when we can properly resolve it. */ f->sub.unresolved = field_proto; - if (f->label_ == kUpb_Label_Required && - upb_FileDef_Syntax(f->file) == kUpb_Syntax_Proto3) { - _upb_DefBuilder_Errf(ctx, "proto3 fields cannot be required (%s)", - f->full_name); - } - if (UPB_DESC(FieldDescriptorProto_has_oneof_index)(field_proto)) { - int oneof_index = UPB_DESC(FieldDescriptorProto_oneof_index)(field_proto); - if (upb_FieldDef_Label(f) != kUpb_Label_Optional) { _upb_DefBuilder_Errf(ctx, "fields in oneof must have OPTIONAL label (%s)", f->full_name); } - - if (!m) { - _upb_DefBuilder_Errf(ctx, "oneof field (%s) has no containing msg", - f->full_name); - } - - if (oneof_index >= upb_MessageDef_OneofCount(m)) { - _upb_DefBuilder_Errf(ctx, "oneof_index out of range (%s)", f->full_name); - } - - upb_OneofDef* oneof = (upb_OneofDef*)upb_MessageDef_Oneof(m, oneof_index); - f->scope.oneof = oneof; - - _upb_OneofDef_Insert(ctx, oneof, f, name.data, name.size); - } - - UPB_DEF_SET_OPTIONS(f->opts, FieldDescriptorProto, FieldOptions, field_proto); - - if (UPB_DESC(FieldOptions_has_packed)(f->opts)) { - f->is_packed = UPB_DESC(FieldOptions_packed)(f->opts); - } else { - f->is_packed = upb_FileDef_Syntax(f->file) == kUpb_Syntax_Proto3; } f->has_presence = (!upb_FieldDef_IsRepeated(f)) && (f->type_ == kUpb_FieldType_Message || f->type_ == kUpb_FieldType_Group || upb_FieldDef_ContainingOneof(f) || - (upb_FileDef_Syntax(f->file) == kUpb_Syntax_Proto2)); + UPB_DESC(FeatureSet_field_presence)(f->resolved_features) != + UPB_DESC(FeatureSet_IMPLICIT)); } static void _upb_FieldDef_CreateExt(upb_DefBuilder* ctx, const char* prefix, - const UPB_DESC(FieldDescriptorProto) * + const UPB_DESC(FeatureSet*) parent_features, + const UPB_DESC(FieldDescriptorProto*) field_proto, upb_MessageDef* m, upb_FieldDef* f) { f->is_extension = true; - _upb_FieldDef_Create(ctx, prefix, field_proto, m, f); + _upb_FieldDef_Create(ctx, prefix, parent_features, field_proto, m, f); if (UPB_DESC(FieldDescriptorProto_has_oneof_index)(field_proto)) { _upb_DefBuilder_Errf(ctx, "oneof_index provided for extension field (%s)", @@ -9118,16 +9661,19 @@ static void _upb_FieldDef_CreateExt(upb_DefBuilder* ctx, const char* prefix, f->layout_index = ctx->ext_count++; if (ctx->layout) { - UPB_ASSERT(_upb_FieldDef_ExtensionMiniTable(f)->field.number == f->number_); + UPB_ASSERT(upb_MiniTableExtension_Number( + _upb_FieldDef_ExtensionMiniTable(f)) == f->number_); } } static void _upb_FieldDef_CreateNotExt(upb_DefBuilder* ctx, const char* prefix, - const UPB_DESC(FieldDescriptorProto) * + const UPB_DESC(FeatureSet*) + parent_features, + const UPB_DESC(FieldDescriptorProto*) field_proto, upb_MessageDef* m, upb_FieldDef* f) { f->is_extension = false; - _upb_FieldDef_Create(ctx, prefix, field_proto, m, f); + _upb_FieldDef_Create(ctx, prefix, parent_features, field_proto, m, f); if (!UPB_DESC(FieldDescriptorProto_has_oneof_index)(field_proto)) { if (f->is_proto3_optional) { @@ -9141,10 +9687,11 @@ static void _upb_FieldDef_CreateNotExt(upb_DefBuilder* ctx, const char* prefix, _upb_MessageDef_InsertField(ctx, m, f); } -upb_FieldDef* _upb_Extensions_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(FieldDescriptorProto) * const* protos, const char* prefix, - upb_MessageDef* m) { +upb_FieldDef* _upb_Extensions_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(FieldDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + const char* prefix, upb_MessageDef* m) { _upb_DefType_CheckPadding(sizeof(upb_FieldDef)); upb_FieldDef* defs = (upb_FieldDef*)_upb_DefBuilder_Alloc(ctx, sizeof(upb_FieldDef) * n); @@ -9152,17 +9699,19 @@ upb_FieldDef* _upb_Extensions_New( for (int i = 0; i < n; i++) { upb_FieldDef* f = &defs[i]; - _upb_FieldDef_CreateExt(ctx, prefix, protos[i], m, f); + _upb_FieldDef_CreateExt(ctx, prefix, parent_features, protos[i], m, f); f->index_ = i; } return defs; } -upb_FieldDef* _upb_FieldDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(FieldDescriptorProto) * const* protos, const char* prefix, - upb_MessageDef* m, bool* is_sorted) { +upb_FieldDef* _upb_FieldDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(FieldDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + const char* prefix, upb_MessageDef* m, + bool* is_sorted) { _upb_DefType_CheckPadding(sizeof(upb_FieldDef)); upb_FieldDef* defs = (upb_FieldDef*)_upb_DefBuilder_Alloc(ctx, sizeof(upb_FieldDef) * n); @@ -9171,7 +9720,7 @@ upb_FieldDef* _upb_FieldDefs_New( for (int i = 0; i < n; i++) { upb_FieldDef* f = &defs[i]; - _upb_FieldDef_CreateNotExt(ctx, prefix, protos[i], m, f); + _upb_FieldDef_CreateNotExt(ctx, prefix, parent_features, protos[i], m, f); f->index_ = i; if (!ctx->layout) { // Speculate that the def fields are sorted. We will always sort the @@ -9308,7 +9857,7 @@ void _upb_FieldDef_BuildMiniTableExtension(upb_DefBuilder* ctx, const upb_MiniTableExtension* ext = _upb_FieldDef_ExtensionMiniTable(f); if (ctx->layout) { - UPB_ASSERT(upb_FieldDef_Number(f) == ext->field.number); + UPB_ASSERT(upb_FieldDef_Number(f) == upb_MiniTableExtension_Number(ext)); } else { upb_StringView desc; if (!upb_FieldDef_MiniDescriptorEncode(f, ctx->tmp_arena, &desc)) { @@ -9318,9 +9867,11 @@ void _upb_FieldDef_BuildMiniTableExtension(upb_DefBuilder* ctx, upb_MiniTableExtension* mut_ext = (upb_MiniTableExtension*)ext; upb_MiniTableSub sub = {NULL}; if (upb_FieldDef_IsSubMessage(f)) { - sub.submsg = upb_MessageDef_MiniTable(f->sub.msgdef); + const upb_MiniTable* submsg = upb_MessageDef_MiniTable(f->sub.msgdef); + sub = upb_MiniTableSub_FromMessage(submsg); } else if (_upb_FieldDef_IsClosedEnum(f)) { - sub.subenum = _upb_EnumDef_MiniTable(f->sub.enumdef); + const upb_MiniTableEnum* subenum = _upb_EnumDef_MiniTable(f->sub.enumdef); + sub = upb_MiniTableSub_FromEnum(subenum); } bool ok2 = upb_MiniTableExtension_Init(desc.data, desc.size, mut_ext, upb_MessageDef_MiniTable(f->msgdef), @@ -9375,11 +9926,16 @@ void _upb_FieldDef_Resolve(upb_DefBuilder* ctx, const char* prefix, } +#include +#include +#include + // Must be last. struct upb_FileDef { - const UPB_DESC(FileOptions) * opts; + const UPB_DESC(FileOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; const char* name; const char* package; UPB_DESC(Edition) edition; @@ -9405,10 +9961,29 @@ struct upb_FileDef { upb_Syntax syntax; }; +UPB_API const char* upb_FileDef_EditionName(int edition) { + // TODO Synchronize this with descriptor.proto better. + switch (edition) { + case UPB_DESC(EDITION_PROTO2): + return "PROTO2"; + case UPB_DESC(EDITION_PROTO3): + return "PROTO3"; + case UPB_DESC(EDITION_2023): + return "2023"; + default: + return "UNKNOWN"; + } +} + const UPB_DESC(FileOptions) * upb_FileDef_Options(const upb_FileDef* f) { return f->opts; } +const UPB_DESC(FeatureSet) * + upb_FileDef_ResolvedFeatures(const upb_FileDef* f) { + return f->resolved_features; +} + bool upb_FileDef_HasOptions(const upb_FileDef* f) { return f->opts != (void*)kUpbDefOptDefault; } @@ -9525,6 +10100,49 @@ static int count_exts_in_msg(const UPB_DESC(DescriptorProto) * msg_proto) { return ext_count; } +const UPB_DESC(FeatureSet*) + _upb_FileDef_FindEdition(upb_DefBuilder* ctx, int edition) { + const UPB_DESC(FeatureSetDefaults)* defaults = + upb_DefPool_FeatureSetDefaults(ctx->symtab); + + int min = UPB_DESC(FeatureSetDefaults_minimum_edition)(defaults); + int max = UPB_DESC(FeatureSetDefaults_maximum_edition)(defaults); + if (edition < min) { + _upb_DefBuilder_Errf(ctx, + "Edition %s is earlier than the minimum edition %s " + "given in the defaults", + upb_FileDef_EditionName(edition), + upb_FileDef_EditionName(min)); + return NULL; + } + if (edition > max) { + _upb_DefBuilder_Errf(ctx, + "Edition %s is later than the maximum edition %s " + "given in the defaults", + upb_FileDef_EditionName(edition), + upb_FileDef_EditionName(max)); + return NULL; + } + + size_t n; + const UPB_DESC(FeatureSetDefaults_FeatureSetEditionDefault)* const* d = + UPB_DESC(FeatureSetDefaults_defaults)(defaults, &n); + const UPB_DESC(FeatureSet)* ret = NULL; + for (size_t i = 0; i < n; i++) { + if (UPB_DESC(FeatureSetDefaults_FeatureSetEditionDefault_edition)(d[i]) > + edition) { + break; + } + ret = UPB_DESC(FeatureSetDefaults_FeatureSetEditionDefault_features)(d[i]); + } + if (ret == NULL) { + _upb_DefBuilder_Errf(ctx, "No valid default found for edition %s", + upb_FileDef_EditionName(edition)); + return NULL; + } + return ret; +} + // Allocate and initialize one file def, and add it to the context object. void _upb_FileDef_Create(upb_DefBuilder* ctx, const UPB_DESC(FileDescriptorProto) * file_proto) { @@ -9553,11 +10171,12 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx, if (ctx->layout) { // We are using the ext layouts that were passed in. - file->ext_layouts = ctx->layout->exts; - if (ctx->layout->ext_count != file->ext_count) { + file->ext_layouts = ctx->layout->UPB_PRIVATE(exts); + const int mt_ext_count = upb_MiniTableFile_ExtensionCount(ctx->layout); + if (mt_ext_count != file->ext_count) { _upb_DefBuilder_Errf(ctx, "Extension count did not match layout (%d vs %d)", - ctx->layout->ext_count, file->ext_count); + mt_ext_count, file->ext_count); } } else { // We are building ext layouts from scratch. @@ -9593,21 +10212,33 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx, if (streql_view(syntax, "proto2")) { file->syntax = kUpb_Syntax_Proto2; + file->edition = UPB_DESC(EDITION_PROTO2); } else if (streql_view(syntax, "proto3")) { file->syntax = kUpb_Syntax_Proto3; + file->edition = UPB_DESC(EDITION_PROTO3); } else if (streql_view(syntax, "editions")) { file->syntax = kUpb_Syntax_Editions; + file->edition = UPB_DESC(FileDescriptorProto_edition)(file_proto); } else { _upb_DefBuilder_Errf(ctx, "Invalid syntax '" UPB_STRINGVIEW_FORMAT "'", UPB_STRINGVIEW_ARGS(syntax)); } } else { file->syntax = kUpb_Syntax_Proto2; + file->edition = UPB_DESC(EDITION_PROTO2); } // Read options. UPB_DEF_SET_OPTIONS(file->opts, FileDescriptorProto, FileOptions, file_proto); + // Resolve features. + const UPB_DESC(FeatureSet*) edition_defaults = + _upb_FileDef_FindEdition(ctx, file->edition); + const UPB_DESC(FeatureSet*) unresolved = + UPB_DESC(FileOptions_features)(file->opts); + file->resolved_features = + _upb_DefBuilder_ResolveFeatures(ctx, edition_defaults, unresolved); + // Verify dependencies. strs = UPB_DESC(FileDescriptorProto_dependency)(file_proto, &n); file->dep_count = n; @@ -9653,22 +10284,26 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx, // Create enums. enums = UPB_DESC(FileDescriptorProto_enum_type)(file_proto, &n); file->top_lvl_enum_count = n; - file->top_lvl_enums = _upb_EnumDefs_New(ctx, n, enums, NULL); + file->top_lvl_enums = + _upb_EnumDefs_New(ctx, n, enums, file->resolved_features, NULL); // Create extensions. exts = UPB_DESC(FileDescriptorProto_extension)(file_proto, &n); file->top_lvl_ext_count = n; - file->top_lvl_exts = _upb_Extensions_New(ctx, n, exts, file->package, NULL); + file->top_lvl_exts = _upb_Extensions_New( + ctx, n, exts, file->resolved_features, file->package, NULL); // Create messages. msgs = UPB_DESC(FileDescriptorProto_message_type)(file_proto, &n); file->top_lvl_msg_count = n; - file->top_lvl_msgs = _upb_MessageDefs_New(ctx, n, msgs, NULL); + file->top_lvl_msgs = + _upb_MessageDefs_New(ctx, n, msgs, file->resolved_features, NULL); // Create services. services = UPB_DESC(FileDescriptorProto_service)(file_proto, &n); file->service_count = n; - file->services = _upb_ServiceDefs_New(ctx, n, services); + file->services = + _upb_ServiceDefs_New(ctx, n, services, file->resolved_features); // Now that all names are in the table, build layouts and resolve refs. @@ -9806,15 +10441,15 @@ const void* _upb_DefBuilder_ResolveAny(upb_DefBuilder* ctx, if (sym.size == 0) goto notfound; upb_value v; if (sym.data[0] == '.') { - /* Symbols starting with '.' are absolute, so we do a single lookup. - * Slice to omit the leading '.' */ + // Symbols starting with '.' are absolute, so we do a single lookup. + // Slice to omit the leading '.' if (!_upb_DefPool_LookupSym(ctx->symtab, sym.data + 1, sym.size - 1, &v)) { goto notfound; } } else { - /* Remove components from base until we find an entry or run out. */ + // Remove components from base until we find an entry or run out. size_t baselen = base ? strlen(base) : 0; - char* tmp = malloc(sym.size + baselen + 1); + char* tmp = upb_gmalloc(sym.size + baselen + 1); while (1) { char* p = tmp; if (baselen) { @@ -9828,11 +10463,11 @@ const void* _upb_DefBuilder_ResolveAny(upb_DefBuilder* ctx, break; } if (!remove_component(tmp, &baselen)) { - free(tmp); + upb_gfree(tmp); goto notfound; } } - free(tmp); + upb_gfree(tmp); } *type = _upb_DefType_Type(v); @@ -10031,6 +10666,77 @@ void _upb_DefBuilder_CheckIdentSlow(upb_DefBuilder* ctx, upb_StringView name, UPB_ASSERT(false); } +upb_StringView _upb_DefBuilder_MakeKey(upb_DefBuilder* ctx, + const UPB_DESC(FeatureSet*) parent, + upb_StringView key) { + size_t need = key.size + sizeof(void*); + if (ctx->tmp_buf_size < need) { + ctx->tmp_buf_size = UPB_MAX(64, upb_Log2Ceiling(need)); + ctx->tmp_buf = upb_Arena_Malloc(ctx->tmp_arena, ctx->tmp_buf_size); + if (!ctx->tmp_buf) _upb_DefBuilder_OomErr(ctx); + } + + memcpy(ctx->tmp_buf, &parent, sizeof(void*)); + memcpy(ctx->tmp_buf + sizeof(void*), key.data, key.size); + return upb_StringView_FromDataAndSize(ctx->tmp_buf, need); +} + +bool _upb_DefBuilder_GetOrCreateFeatureSet(upb_DefBuilder* ctx, + const UPB_DESC(FeatureSet*) parent, + upb_StringView key, + UPB_DESC(FeatureSet**) set) { + upb_StringView k = _upb_DefBuilder_MakeKey(ctx, parent, key); + upb_value v; + if (upb_strtable_lookup2(&ctx->feature_cache, k.data, k.size, &v)) { + *set = upb_value_getptr(v); + return false; + } + + *set = + upb_Message_DeepClone(parent, UPB_DESC_MINITABLE(FeatureSet), ctx->arena); + if (!*set) _upb_DefBuilder_OomErr(ctx); + + v = upb_value_ptr(*set); + if (!upb_strtable_insert(&ctx->feature_cache, k.data, k.size, v, + ctx->tmp_arena)) { + _upb_DefBuilder_OomErr(ctx); + } + + return true; +} + +const UPB_DESC(FeatureSet*) + _upb_DefBuilder_DoResolveFeatures(upb_DefBuilder* ctx, + const UPB_DESC(FeatureSet*) parent, + const UPB_DESC(FeatureSet*) child, + bool is_implicit) { + assert(parent); + if (!child) return parent; + + if (child && !is_implicit && + upb_FileDef_Syntax(ctx->file) != kUpb_Syntax_Editions) { + _upb_DefBuilder_Errf(ctx, "Features can only be specified for editions"); + } + + UPB_DESC(FeatureSet*) resolved; + size_t child_size; + const char* child_bytes = + UPB_DESC(FeatureSet_serialize)(child, ctx->tmp_arena, &child_size); + if (!child_bytes) _upb_DefBuilder_OomErr(ctx); + + upb_StringView key = upb_StringView_FromDataAndSize(child_bytes, child_size); + if (!_upb_DefBuilder_GetOrCreateFeatureSet(ctx, parent, key, &resolved)) { + return resolved; + } + + upb_DecodeStatus dec_status = + upb_Decode(child_bytes, child_size, resolved, + UPB_DESC_MINITABLE(FeatureSet), NULL, 0, ctx->arena); + if (dec_status != kUpb_DecodeStatus_Ok) _upb_DefBuilder_OomErr(ctx); + + return resolved; +} + #include @@ -10056,6 +10762,7 @@ char* upb_strdup2(const char* s, size_t len, upb_Arena* a) { } +#include #include @@ -10084,9 +10791,7 @@ const upb_FieldDef* upb_Message_WhichOneof(const upb_Message* msg, upb_MessageValue upb_Message_GetFieldByDef(const upb_Message* msg, const upb_FieldDef* f) { upb_MessageValue default_val = upb_FieldDef_Default(f); - upb_MessageValue ret; - _upb_Message_GetField(msg, upb_FieldDef_MiniTable(f), &default_val, &ret); - return ret; + return upb_Message_GetField(msg, upb_FieldDef_MiniTable(f), default_val); } upb_MutableMessageValue upb_Message_Mutable(upb_Message* msg, @@ -10130,7 +10835,7 @@ make: bool upb_Message_SetFieldByDef(upb_Message* msg, const upb_FieldDef* f, upb_MessageValue val, upb_Arena* a) { - return _upb_Message_SetField(msg, upb_FieldDef_MiniTable(f), &val, a); + return upb_Message_SetField(msg, upb_FieldDef_MiniTable(f), val, a); } void upb_Message_ClearFieldByDef(upb_Message* msg, const upb_FieldDef* f) { @@ -10158,7 +10863,7 @@ bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m, if (upb_MiniTableField_HasPresence(field)) { if (!upb_Message_HasFieldByDef(msg, f)) continue; } else { - switch (upb_FieldMode_Get(field)) { + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(field)) { case kUpb_FieldMode_Map: if (!val.map_val || upb_Map_Size(val.map_val) == 0) continue; break; @@ -10166,7 +10871,8 @@ bool upb_Message_Next(const upb_Message* msg, const upb_MessageDef* m, if (!val.array_val || upb_Array_Size(val.array_val) == 0) continue; break; case kUpb_FieldMode_Scalar: - if (!_upb_MiniTable_ValueIsNonZero(&val, field)) continue; + if (UPB_PRIVATE(_upb_MiniTableField_DataIsZero)(field, &val)) + continue; break; } } @@ -10250,11 +10956,16 @@ bool upb_Message_DiscardUnknown(upb_Message* msg, const upb_MessageDef* m, } +#include +#include +#include + // Must be last. struct upb_MessageDef { - const UPB_DESC(MessageOptions) * opts; + const UPB_DESC(MessageOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; const upb_MiniTable* layout; const upb_FileDef* file; const upb_MessageDef* containing_type; @@ -10292,6 +11003,9 @@ struct upb_MessageDef { bool in_message_set; bool is_sorted; upb_WellKnown well_known_type; +#if UINTPTR_MAX == 0xffffffff + uint32_t padding; // Increase size to a multiple of 8. +#endif }; static void assign_msg_wellknowntype(upb_MessageDef* m) { @@ -10360,6 +11074,11 @@ bool upb_MessageDef_HasOptions(const upb_MessageDef* m) { return m->opts != (void*)kUpbDefOptDefault; } +const UPB_DESC(FeatureSet) * + upb_MessageDef_ResolvedFeatures(const upb_MessageDef* m) { + return m->resolved_features; +} + const char* upb_MessageDef_FullName(const upb_MessageDef* m) { return m->full_name; } @@ -10623,10 +11342,9 @@ void _upb_MessageDef_InsertField(upb_DefBuilder* ctx, upb_MessageDef* m, _upb_MessageDef_Insert(m, shortname, shortnamelen, field_v, ctx->arena); if (!ok) _upb_DefBuilder_OomErr(ctx); - // TODO: Once editions is supported this should turn into a - // check on LEGACY_BEST_EFFORT if (strcmp(shortname, json_name) != 0 && - upb_FileDef_Syntax(m->file) == kUpb_Syntax_Proto3 && + UPB_DESC(FeatureSet_json_format)(m->resolved_features) == + UPB_DESC(FeatureSet_ALLOW) && upb_strtable_lookup(&m->ntof, json_name, &v)) { _upb_DefBuilder_Errf( ctx, "duplicate json_name for (%s) with original field name (%s)", @@ -10654,9 +11372,8 @@ void _upb_MessageDef_CreateMiniTable(upb_DefBuilder* ctx, upb_MessageDef* m) { if (ctx->layout == NULL) { m->layout = _upb_MessageDef_MakeMiniTable(ctx, m); } else { - UPB_ASSERT(ctx->msg_count < ctx->layout->msg_count); - m->layout = ctx->layout->msgs[ctx->msg_count++]; - UPB_ASSERT(m->field_count == m->layout->field_count); + m->layout = upb_MiniTableFile_Message(ctx->layout, ctx->msg_count++); + UPB_ASSERT(m->field_count == m->layout->UPB_PRIVATE(field_count)); // We don't need the result of this call, but it will assign layout_index // for all the fields in O(n lg n) time. @@ -10692,9 +11409,9 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx, UPB_ASSERT(layout_index < m->field_count); upb_MiniTableField* mt_f = - (upb_MiniTableField*)&m->layout->fields[layout_index]; + (upb_MiniTableField*)&m->layout->UPB_PRIVATE(fields)[layout_index]; if (sub_m) { - if (!mt->subs) { + if (!mt->UPB_PRIVATE(subs)) { _upb_DefBuilder_Errf(ctx, "unexpected submsg for (%s)", m->full_name); } UPB_ASSERT(mt_f); @@ -10714,8 +11431,9 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx, for (int i = 0; i < m->field_count; i++) { const upb_FieldDef* f = upb_MessageDef_Field(m, i); const int layout_index = _upb_FieldDef_LayoutIndex(f); - UPB_ASSERT(layout_index < m->layout->field_count); - const upb_MiniTableField* mt_f = &m->layout->fields[layout_index]; + UPB_ASSERT(layout_index < m->layout->UPB_PRIVATE(field_count)); + const upb_MiniTableField* mt_f = + &m->layout->UPB_PRIVATE(fields)[layout_index]; UPB_ASSERT(upb_FieldDef_Type(f) == upb_MiniTableField_Type(mt_f)); UPB_ASSERT(upb_FieldDef_CType(f) == upb_MiniTableField_CType(mt_f)); UPB_ASSERT(upb_FieldDef_HasPresence(f) == @@ -10743,7 +11461,8 @@ static bool _upb_MessageDef_ValidateUtf8(const upb_MessageDef* m) { static uint64_t _upb_MessageDef_Modifiers(const upb_MessageDef* m) { uint64_t out = 0; - if (upb_FileDef_Syntax(m->file) == kUpb_Syntax_Proto3) { + if (UPB_DESC(FeatureSet_repeated_field_encoding(m->resolved_features)) == + UPB_DESC(FeatureSet_PACKED)) { out |= kUpb_MessageModifier_DefaultIsPacked; } @@ -10857,7 +11576,8 @@ static upb_StringView* _upb_ReservedNames_New(upb_DefBuilder* ctx, int n, } static void create_msgdef(upb_DefBuilder* ctx, const char* prefix, - const UPB_DESC(DescriptorProto) * msg_proto, + const UPB_DESC(DescriptorProto*) msg_proto, + const UPB_DESC(FeatureSet*) parent_features, const upb_MessageDef* containing_type, upb_MessageDef* m) { const UPB_DESC(OneofDescriptorProto)* const* oneofs; @@ -10869,6 +11589,10 @@ static void create_msgdef(upb_DefBuilder* ctx, const char* prefix, size_t n_ext_range, n_res_range, n_res_name; upb_StringView name; + UPB_DEF_SET_OPTIONS(m->opts, DescriptorProto, MessageOptions, msg_proto); + m->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, UPB_DESC(MessageOptions_features)(m->opts)); + // Must happen before _upb_DefBuilder_Add() m->file = _upb_DefBuilder_File(ctx); @@ -10897,14 +11621,12 @@ static void create_msgdef(upb_DefBuilder* ctx, const char* prefix, ok = upb_strtable_init(&m->jtof, n_field, ctx->arena); if (!ok) _upb_DefBuilder_OomErr(ctx); - UPB_DEF_SET_OPTIONS(m->opts, DescriptorProto, MessageOptions, msg_proto); - m->oneof_count = n_oneof; - m->oneofs = _upb_OneofDefs_New(ctx, n_oneof, oneofs, m); + m->oneofs = _upb_OneofDefs_New(ctx, n_oneof, oneofs, m->resolved_features, m); m->field_count = n_field; - m->fields = - _upb_FieldDefs_New(ctx, n_field, fields, m->full_name, m, &m->is_sorted); + m->fields = _upb_FieldDefs_New(ctx, n_field, fields, m->resolved_features, + m->full_name, m, &m->is_sorted); // Message Sets may not contain fields. if (UPB_UNLIKELY(UPB_DESC(MessageOptions_message_set_wire_format)(m->opts))) { @@ -10914,7 +11636,8 @@ static void create_msgdef(upb_DefBuilder* ctx, const char* prefix, } m->ext_range_count = n_ext_range; - m->ext_ranges = _upb_ExtensionRanges_New(ctx, n_ext_range, ext_ranges, m); + m->ext_ranges = _upb_ExtensionRanges_New(ctx, n_ext_range, ext_ranges, + m->resolved_features, m); m->res_range_count = n_res_range; m->res_ranges = @@ -10932,23 +11655,29 @@ static void create_msgdef(upb_DefBuilder* ctx, const char* prefix, const UPB_DESC(EnumDescriptorProto)* const* enums = UPB_DESC(DescriptorProto_enum_type)(msg_proto, &n_enum); m->nested_enum_count = n_enum; - m->nested_enums = _upb_EnumDefs_New(ctx, n_enum, enums, m); + m->nested_enums = + _upb_EnumDefs_New(ctx, n_enum, enums, m->resolved_features, m); const UPB_DESC(FieldDescriptorProto)* const* exts = UPB_DESC(DescriptorProto_extension)(msg_proto, &n_ext); m->nested_ext_count = n_ext; - m->nested_exts = _upb_Extensions_New(ctx, n_ext, exts, m->full_name, m); + m->nested_exts = _upb_Extensions_New(ctx, n_ext, exts, m->resolved_features, + m->full_name, m); const UPB_DESC(DescriptorProto)* const* msgs = UPB_DESC(DescriptorProto_nested_type)(msg_proto, &n_msg); m->nested_msg_count = n_msg; - m->nested_msgs = _upb_MessageDefs_New(ctx, n_msg, msgs, m); + m->nested_msgs = + _upb_MessageDefs_New(ctx, n_msg, msgs, m->resolved_features, m); } // Allocate and initialize an array of |n| message defs. -upb_MessageDef* _upb_MessageDefs_New( - upb_DefBuilder* ctx, int n, const UPB_DESC(DescriptorProto) * const* protos, - const upb_MessageDef* containing_type) { +upb_MessageDef* _upb_MessageDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(DescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) + parent_features, + const upb_MessageDef* containing_type) { _upb_DefType_CheckPadding(sizeof(upb_MessageDef)); const char* name = containing_type ? containing_type->full_name @@ -10956,7 +11685,8 @@ upb_MessageDef* _upb_MessageDefs_New( upb_MessageDef* m = _upb_DefBuilder_Alloc(ctx, sizeof(upb_MessageDef) * n); for (int i = 0; i < n; i++) { - create_msgdef(ctx, name, protos[i], containing_type, &m[i]); + create_msgdef(ctx, name, protos[i], parent_features, containing_type, + &m[i]); } return m; } @@ -11015,7 +11745,8 @@ upb_MessageReservedRange* _upb_MessageReservedRanges_New( // Must be last. struct upb_MethodDef { - const UPB_DESC(MethodOptions) * opts; + const UPB_DESC(MethodOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; upb_ServiceDef* service; const char* full_name; const upb_MessageDef* input_type; @@ -11041,6 +11772,11 @@ bool upb_MethodDef_HasOptions(const upb_MethodDef* m) { return m->opts != (void*)kUpbDefOptDefault; } +const UPB_DESC(FeatureSet) * + upb_MethodDef_ResolvedFeatures(const upb_MethodDef* m) { + return m->resolved_features; +} + const char* upb_MethodDef_FullName(const upb_MethodDef* m) { return m->full_name; } @@ -11068,8 +11804,14 @@ bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m) { } static void create_method(upb_DefBuilder* ctx, - const UPB_DESC(MethodDescriptorProto) * method_proto, + const UPB_DESC(MethodDescriptorProto*) method_proto, + const UPB_DESC(FeatureSet*) parent_features, upb_ServiceDef* s, upb_MethodDef* m) { + UPB_DEF_SET_OPTIONS(m->opts, MethodDescriptorProto, MethodOptions, + method_proto); + m->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, UPB_DESC(MethodOptions_features)(m->opts)); + upb_StringView name = UPB_DESC(MethodDescriptorProto_name)(method_proto); m->service = s; @@ -11087,18 +11829,17 @@ static void create_method(upb_DefBuilder* ctx, ctx, m->full_name, m->full_name, UPB_DESC(MethodDescriptorProto_output_type)(method_proto), UPB_DEFTYPE_MSG); - - UPB_DEF_SET_OPTIONS(m->opts, MethodDescriptorProto, MethodOptions, - method_proto); } // Allocate and initialize an array of |n| method defs belonging to |s|. -upb_MethodDef* _upb_MethodDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(MethodDescriptorProto) * const* protos, upb_ServiceDef* s) { +upb_MethodDef* _upb_MethodDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(MethodDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + upb_ServiceDef* s) { upb_MethodDef* m = _upb_DefBuilder_Alloc(ctx, sizeof(upb_MethodDef) * n); for (int i = 0; i < n; i++) { - create_method(ctx, protos[i], s, &m[i]); + create_method(ctx, protos[i], parent_features, s, &m[i]); m[i].index = i; } return m; @@ -11113,7 +11854,8 @@ upb_MethodDef* _upb_MethodDefs_New( // Must be last. struct upb_OneofDef { - const UPB_DESC(OneofOptions) * opts; + const UPB_DESC(OneofOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; const upb_MessageDef* parent; const char* full_name; int field_count; @@ -11121,9 +11863,6 @@ struct upb_OneofDef { const upb_FieldDef** fields; upb_strtable ntof; // lookup a field by name upb_inttable itof; // lookup a field by number (index) -#if UINTPTR_MAX == 0xffffffff - uint32_t padding; // Increase size to a multiple of 8. -#endif }; upb_OneofDef* _upb_OneofDef_At(const upb_OneofDef* o, int i) { @@ -11138,6 +11877,11 @@ bool upb_OneofDef_HasOptions(const upb_OneofDef* o) { return o->opts != (void*)kUpbDefOptDefault; } +const UPB_DESC(FeatureSet) * + upb_OneofDef_ResolvedFeatures(const upb_OneofDef* o) { + return o->resolved_features; +} + const char* upb_OneofDef_FullName(const upb_OneofDef* o) { return o->full_name; } @@ -11257,9 +12001,15 @@ size_t _upb_OneofDefs_Finalize(upb_DefBuilder* ctx, upb_MessageDef* m) { } static void create_oneofdef(upb_DefBuilder* ctx, upb_MessageDef* m, - const UPB_DESC(OneofDescriptorProto) * oneof_proto, + const UPB_DESC(OneofDescriptorProto*) oneof_proto, + const UPB_DESC(FeatureSet*) parent_features, const upb_OneofDef* _o) { upb_OneofDef* o = (upb_OneofDef*)_o; + + UPB_DEF_SET_OPTIONS(o->opts, OneofDescriptorProto, OneofOptions, oneof_proto); + o->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, UPB_DESC(OneofOptions_features)(o->opts)); + upb_StringView name = UPB_DESC(OneofDescriptorProto_name)(oneof_proto); o->parent = m; @@ -11268,8 +12018,6 @@ static void create_oneofdef(upb_DefBuilder* ctx, upb_MessageDef* m, o->field_count = 0; o->synthetic = false; - UPB_DEF_SET_OPTIONS(o->opts, OneofDescriptorProto, OneofOptions, oneof_proto); - if (upb_MessageDef_FindByNameWithSize(m, name.data, name.size, NULL, NULL)) { _upb_DefBuilder_Errf(ctx, "duplicate oneof name (%s)", o->full_name); } @@ -11286,14 +12034,16 @@ static void create_oneofdef(upb_DefBuilder* ctx, upb_MessageDef* m, } // Allocate and initialize an array of |n| oneof defs. -upb_OneofDef* _upb_OneofDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(OneofDescriptorProto) * const* protos, upb_MessageDef* m) { +upb_OneofDef* _upb_OneofDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(OneofDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + upb_MessageDef* m) { _upb_DefType_CheckPadding(sizeof(upb_OneofDef)); upb_OneofDef* o = _upb_DefBuilder_Alloc(ctx, sizeof(upb_OneofDef) * n); for (int i = 0; i < n; i++) { - create_oneofdef(ctx, m, protos[i], &o[i]); + create_oneofdef(ctx, m, protos[i], parent_features, &o[i]); } return o; } @@ -11303,12 +12053,16 @@ upb_OneofDef* _upb_OneofDefs_New( // Must be last. struct upb_ServiceDef { - const UPB_DESC(ServiceOptions) * opts; + const UPB_DESC(ServiceOptions*) opts; + const UPB_DESC(FeatureSet*) resolved_features; const upb_FileDef* file; const char* full_name; upb_MethodDef* methods; int method_count; int index; +#if UINTPTR_MAX == 0xffffffff + uint32_t padding; // Increase size to a multiple of 8. +#endif }; upb_ServiceDef* _upb_ServiceDef_At(const upb_ServiceDef* s, int index) { @@ -11324,6 +12078,11 @@ bool upb_ServiceDef_HasOptions(const upb_ServiceDef* s) { return s->opts != (void*)kUpbDefOptDefault; } +const UPB_DESC(FeatureSet) * + upb_ServiceDef_ResolvedFeatures(const upb_ServiceDef* s) { + return s->resolved_features; +} + const char* upb_ServiceDef_FullName(const upb_ServiceDef* s) { return s->full_name; } @@ -11359,37 +12118,40 @@ const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s, } static void create_service(upb_DefBuilder* ctx, - const UPB_DESC(ServiceDescriptorProto) * svc_proto, + const UPB_DESC(ServiceDescriptorProto*) svc_proto, + const UPB_DESC(FeatureSet*) parent_features, upb_ServiceDef* s) { - upb_StringView name; - size_t n; + UPB_DEF_SET_OPTIONS(s->opts, ServiceDescriptorProto, ServiceOptions, + svc_proto); + s->resolved_features = _upb_DefBuilder_ResolveFeatures( + ctx, parent_features, UPB_DESC(ServiceOptions_features)(s->opts)); // Must happen before _upb_DefBuilder_Add() s->file = _upb_DefBuilder_File(ctx); - name = UPB_DESC(ServiceDescriptorProto_name)(svc_proto); + upb_StringView name = UPB_DESC(ServiceDescriptorProto_name)(svc_proto); const char* package = _upb_FileDef_RawPackage(s->file); s->full_name = _upb_DefBuilder_MakeFullName(ctx, package, name); _upb_DefBuilder_Add(ctx, s->full_name, _upb_DefType_Pack(s, UPB_DEFTYPE_SERVICE)); + size_t n; const UPB_DESC(MethodDescriptorProto)* const* methods = UPB_DESC(ServiceDescriptorProto_method)(svc_proto, &n); s->method_count = n; - s->methods = _upb_MethodDefs_New(ctx, n, methods, s); - - UPB_DEF_SET_OPTIONS(s->opts, ServiceDescriptorProto, ServiceOptions, - svc_proto); + s->methods = _upb_MethodDefs_New(ctx, n, methods, s->resolved_features, s); } -upb_ServiceDef* _upb_ServiceDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(ServiceDescriptorProto) * const* protos) { +upb_ServiceDef* _upb_ServiceDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(ServiceDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) + parent_features) { _upb_DefType_CheckPadding(sizeof(upb_ServiceDef)); upb_ServiceDef* s = _upb_DefBuilder_Alloc(ctx, sizeof(upb_ServiceDef) * n); for (int i = 0; i < n; i++) { - create_service(ctx, protos[i], &s[i]); + create_service(ctx, protos[i], parent_features, &s[i]); s[i].index = i; } return s; @@ -11444,6 +12206,27 @@ typedef union { uint32_t size; } wireval; +// Ideally these two functions should take the owning MiniTable pointer as a +// first argument, then we could just put them in mini_table/message.h as nice +// clean getters. But we don't have that so instead we gotta write these +// Frankenfunctions that take an array of subtables. +// TODO: Move these to mini_table/ anyway since there are other places +// that could use them. + +// Returns the MiniTable corresponding to a given MiniTableField +// from an array of MiniTableSubs. +static const upb_MiniTable* _upb_MiniTableSubs_MessageByField( + const upb_MiniTableSub* subs, const upb_MiniTableField* field) { + return upb_MiniTableSub_Message(subs[field->UPB_PRIVATE(submsg_index)]); +} + +// Returns the MiniTableEnum corresponding to a given MiniTableField +// from an array of MiniTableSub. +static const upb_MiniTableEnum* _upb_MiniTableSubs_EnumByField( + const upb_MiniTableSub* subs, const upb_MiniTableField* field) { + return upb_MiniTableSub_Enum(subs[field->UPB_PRIVATE(submsg_index)]); +} + static const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr, upb_Message* msg, const upb_MiniTable* layout); @@ -11469,8 +12252,9 @@ static void _upb_Decoder_VerifyUtf8(upb_Decoder* d, const char* buf, int len) { } static bool _upb_Decoder_Reserve(upb_Decoder* d, upb_Array* arr, size_t elem) { - bool need_realloc = arr->capacity - arr->size < elem; - if (need_realloc && !_upb_array_realloc(arr, arr->size + elem, &d->arena)) { + bool need_realloc = arr->UPB_PRIVATE(capacity) - arr->size < elem; + if (need_realloc && + !UPB_PRIVATE(_upb_Array_Realloc)(arr, arr->size + elem, &d->arena)) { _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } return need_realloc; @@ -11579,15 +12363,15 @@ static upb_Message* _upb_Decoder_NewSubMessage(upb_Decoder* d, const upb_MiniTableSub* subs, const upb_MiniTableField* field, upb_TaggedMessagePtr* target) { - const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(subl); upb_Message* msg = _upb_Message_New(subl, &d->arena); if (!msg) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); - // Extensions should not be unlinked. A message extension should not be + // Extensions should not be unlinked. A message extension should not be // registered until its sub-message type is available to be linked. - bool is_empty = subl == &_kUpb_MiniTable_Empty; - bool is_extension = field->mode & kUpb_LabelFlags_IsExtension; + bool is_empty = UPB_PRIVATE(_upb_MiniTable_IsEmpty)(subl); + bool is_extension = field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsExtension; UPB_ASSERT(!(is_empty && is_extension)); if (is_empty && !(d->options & kUpb_DecodeOption_ExperimentalAllowUnlinked)) { @@ -11603,9 +12387,10 @@ static upb_Message* _upb_Decoder_ReuseSubMessage( upb_Decoder* d, const upb_MiniTableSub* subs, const upb_MiniTableField* field, upb_TaggedMessagePtr* target) { upb_TaggedMessagePtr tagged = *target; - const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(subl); - if (!upb_TaggedMessagePtr_IsEmpty(tagged) || subl == &_kUpb_MiniTable_Empty) { + if (!upb_TaggedMessagePtr_IsEmpty(tagged) || + UPB_PRIVATE(_upb_MiniTable_IsEmpty)(subl)) { return _upb_TaggedMessagePtr_GetMessage(tagged); } @@ -11654,7 +12439,7 @@ static const char* _upb_Decoder_DecodeSubMessage( upb_Decoder* d, const char* ptr, upb_Message* submsg, const upb_MiniTableSub* subs, const upb_MiniTableField* field, int size) { int saved_delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, size); - const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(subl); ptr = _upb_Decoder_RecurseSubMessage(d, ptr, submsg, subl, DECODE_NOGROUP); upb_EpsCopyInputStream_PopLimit(&d->input, ptr, saved_delta); @@ -11685,9 +12470,10 @@ UPB_FORCEINLINE static const char* _upb_Decoder_DecodeKnownGroup( upb_Decoder* d, const char* ptr, upb_Message* submsg, const upb_MiniTableSub* subs, const upb_MiniTableField* field) { - const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(subl); - return _upb_Decoder_DecodeGroup(d, ptr, submsg, subl, field->number); + return _upb_Decoder_DecodeGroup(d, ptr, submsg, subl, + field->UPB_PRIVATE(number)); } static char* upb_Decoder_EncodeVarint32(uint32_t val, char* ptr) { @@ -11707,39 +12493,30 @@ static void _upb_Decoder_AddUnknownVarints(upb_Decoder* d, upb_Message* msg, end = upb_Decoder_EncodeVarint32(val1, end); end = upb_Decoder_EncodeVarint32(val2, end); - if (!_upb_Message_AddUnknown(msg, buf, end - buf, &d->arena)) { + if (!UPB_PRIVATE(_upb_Message_AddUnknown)(msg, buf, end - buf, &d->arena)) { _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } } -UPB_NOINLINE -static bool _upb_Decoder_CheckEnumSlow(upb_Decoder* d, const char* ptr, - upb_Message* msg, - const upb_MiniTableEnum* e, - const upb_MiniTableField* field, - uint32_t v) { - if (_upb_MiniTable_CheckEnumValueSlow(e, v)) return true; - - // Unrecognized enum goes into unknown fields. - // For packed fields the tag could be arbitrarily far in the past, so we - // just re-encode the tag and value here. - uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Varint; - upb_Message* unknown_msg = - field->mode & kUpb_LabelFlags_IsExtension ? d->unknown_msg : msg; - _upb_Decoder_AddUnknownVarints(d, unknown_msg, tag, v); - return false; -} - UPB_FORCEINLINE static bool _upb_Decoder_CheckEnum(upb_Decoder* d, const char* ptr, upb_Message* msg, const upb_MiniTableEnum* e, const upb_MiniTableField* field, wireval* val) { - uint32_t v = val->uint32_val; + const uint32_t v = val->uint32_val; + + if (UPB_LIKELY(upb_MiniTableEnum_CheckValue(e, v))) return true; - _kUpb_FastEnumCheck_Status status = _upb_MiniTable_CheckEnumValueFast(e, v); - if (UPB_LIKELY(status == _kUpb_FastEnumCheck_ValueIsInEnum)) return true; - return _upb_Decoder_CheckEnumSlow(d, ptr, msg, e, field, v); + // Unrecognized enum goes into unknown fields. + // For packed fields the tag could be arbitrarily far in the past, + // so we just re-encode the tag and value here. + const uint32_t tag = + ((uint32_t)field->UPB_PRIVATE(number) << 3) | kUpb_WireType_Varint; + upb_Message* unknown_msg = + field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsExtension ? d->unknown_msg + : msg; + _upb_Decoder_AddUnknownVarints(d, unknown_msg, tag, v); + return false; } UPB_NOINLINE @@ -11749,7 +12526,7 @@ static const char* _upb_Decoder_DecodeEnumArray(upb_Decoder* d, const char* ptr, const upb_MiniTableSub* subs, const upb_MiniTableField* field, wireval* val) { - const upb_MiniTableEnum* e = subs[field->UPB_PRIVATE(submsg_index)].subenum; + const upb_MiniTableEnum* e = _upb_MiniTableSubs_EnumByField(subs, field); if (!_upb_Decoder_CheckEnum(d, ptr, msg, e, field, val)) return ptr; void* mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->size * 4, void); arr->size++; @@ -11820,7 +12597,7 @@ static const char* _upb_Decoder_DecodeEnumPacked( upb_Decoder* d, const char* ptr, upb_Message* msg, upb_Array* arr, const upb_MiniTableSub* subs, const upb_MiniTableField* field, wireval* val) { - const upb_MiniTableEnum* e = subs[field->UPB_PRIVATE(submsg_index)].subenum; + const upb_MiniTableEnum* e = _upb_MiniTableSubs_EnumByField(subs, field); int saved_limit = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, val->size); char* out = UPB_PTR_AT(_upb_array_ptr(arr), arr->size * 4, void); while (!_upb_Decoder_IsDone(d, &ptr)) { @@ -11843,31 +12620,9 @@ static const char* _upb_Decoder_DecodeEnumPacked( upb_Array* _upb_Decoder_CreateArray(upb_Decoder* d, const upb_MiniTableField* field) { - /* Maps descriptor type -> elem_size_lg2. */ - static const uint8_t kElemSizeLg2[] = { - [0] = -1, // invalid descriptor type - [kUpb_FieldType_Double] = 3, - [kUpb_FieldType_Float] = 2, - [kUpb_FieldType_Int64] = 3, - [kUpb_FieldType_UInt64] = 3, - [kUpb_FieldType_Int32] = 2, - [kUpb_FieldType_Fixed64] = 3, - [kUpb_FieldType_Fixed32] = 2, - [kUpb_FieldType_Bool] = 0, - [kUpb_FieldType_String] = UPB_SIZE(3, 4), - [kUpb_FieldType_Group] = UPB_SIZE(2, 3), - [kUpb_FieldType_Message] = UPB_SIZE(2, 3), - [kUpb_FieldType_Bytes] = UPB_SIZE(3, 4), - [kUpb_FieldType_UInt32] = 2, - [kUpb_FieldType_Enum] = 2, - [kUpb_FieldType_SFixed32] = 2, - [kUpb_FieldType_SFixed64] = 3, - [kUpb_FieldType_SInt32] = 2, - [kUpb_FieldType_SInt64] = 3, - }; - - size_t lg2 = kElemSizeLg2[field->UPB_PRIVATE(descriptortype)]; - upb_Array* ret = _upb_Array_New(&d->arena, 4, lg2); + const upb_FieldType field_type = field->UPB_PRIVATE(descriptortype); + const size_t lg2 = upb_FieldType_SizeLg2(field_type); + upb_Array* ret = UPB_PRIVATE(_upb_Array_New)(&d->arena, 4, lg2); if (!ret) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); return ret; } @@ -11962,8 +12717,8 @@ upb_Map* _upb_Decoder_CreateMap(upb_Decoder* d, const upb_MiniTable* entry) { [kUpb_FieldType_SInt64] = 8, }; - const upb_MiniTableField* key_field = &entry->fields[0]; - const upb_MiniTableField* val_field = &entry->fields[1]; + const upb_MiniTableField* key_field = &entry->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* val_field = &entry->UPB_PRIVATE(fields)[1]; char key_size = kSizeInMap[key_field->UPB_PRIVATE(descriptortype)]; char val_size = kSizeInMap[val_field->UPB_PRIVATE(descriptortype)]; UPB_ASSERT(key_field->offset == offsetof(upb_MapEntryData, k)); @@ -11982,12 +12737,12 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr, upb_Map* map = *map_p; upb_MapEntry ent; UPB_ASSERT(upb_MiniTableField_Type(field) == kUpb_FieldType_Message); - const upb_MiniTable* entry = subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* entry = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(entry); - UPB_ASSERT(entry->field_count == 2); - UPB_ASSERT(!upb_IsRepeatedOrMap(&entry->fields[0])); - UPB_ASSERT(!upb_IsRepeatedOrMap(&entry->fields[1])); + UPB_ASSERT(entry->UPB_PRIVATE(field_count) == 2); + UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->UPB_PRIVATE(fields)[0])); + UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->UPB_PRIVATE(fields)[1])); if (!map) { map = _upb_Decoder_CreateMap(d, entry); @@ -11997,11 +12752,14 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr, // Parse map entry. memset(&ent, 0, sizeof(ent)); - if (entry->fields[1].UPB_PRIVATE(descriptortype) == kUpb_FieldType_Message || - entry->fields[1].UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group) { + if (entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) == + kUpb_FieldType_Message || + entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) == + kUpb_FieldType_Group) { // Create proactively to handle the case where it doesn't appear. upb_TaggedMessagePtr msg; - _upb_Decoder_NewSubMessage(d, entry->subs, &entry->fields[1], &msg); + _upb_Decoder_NewSubMessage(d, entry->UPB_PRIVATE(subs), + &entry->UPB_PRIVATE(fields)[1], &msg); ent.data.v.val = upb_value_uintptr(msg); } @@ -12013,14 +12771,15 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr, if (size != 0) { char* buf; size_t size; - uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Delimited; + uint32_t tag = + ((uint32_t)field->UPB_PRIVATE(number) << 3) | kUpb_WireType_Delimited; upb_EncodeStatus status = upb_Encode(&ent.data, entry, 0, &d->arena, &buf, &size); if (status != kUpb_EncodeStatus_Ok) { _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } _upb_Decoder_AddUnknownVarints(d, msg, tag, size); - if (!_upb_Message_AddUnknown(msg, buf, size, &d->arena)) { + if (!UPB_PRIVATE(_upb_Message_AddUnknown)(msg, buf, size, &d->arena)) { _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } } else { @@ -12042,21 +12801,22 @@ static const char* _upb_Decoder_DecodeToSubMessage( if (UPB_UNLIKELY(op == kUpb_DecodeOp_Enum) && !_upb_Decoder_CheckEnum(d, ptr, msg, - subs[field->UPB_PRIVATE(submsg_index)].subenum, + _upb_MiniTableSubs_EnumByField(subs, field), field, val)) { return ptr; } /* Set presence if necessary. */ if (field->presence > 0) { - _upb_sethas_field(msg, field); + UPB_PRIVATE(_upb_Message_SetHasbit)(msg, field); } else if (field->presence < 0) { /* Oneof case */ - uint32_t* oneof_case = _upb_oneofcase_field(msg, field); - if (op == kUpb_DecodeOp_SubMessage && *oneof_case != field->number) { + uint32_t* oneof_case = UPB_PRIVATE(_upb_Message_OneofCasePtr)(msg, field); + if (op == kUpb_DecodeOp_SubMessage && + *oneof_case != field->UPB_PRIVATE(number)) { memset(mem, 0, sizeof(void*)); } - *oneof_case = field->number; + *oneof_case = field->UPB_PRIVATE(number); } /* Store into message. */ @@ -12102,15 +12862,15 @@ static const char* _upb_Decoder_DecodeToSubMessage( UPB_NOINLINE const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, const upb_Message* msg, - const upb_MiniTable* l) { - UPB_ASSERT(l->required_count); + const upb_MiniTable* m) { + UPB_ASSERT(m->UPB_PRIVATE(required_count)); if (UPB_LIKELY((d->options & kUpb_DecodeOption_CheckRequired) == 0)) { return ptr; } uint64_t msg_head; memcpy(&msg_head, msg, 8); msg_head = _upb_BigEndian_Swap64(msg_head); - if (upb_MiniTable_requiredmask(l) & ~msg_head) { + if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) { d->missing_required = true; } return ptr; @@ -12119,11 +12879,11 @@ const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, UPB_FORCEINLINE static bool _upb_Decoder_TryFastDispatch(upb_Decoder* d, const char** ptr, upb_Message* msg, - const upb_MiniTable* layout) { + const upb_MiniTable* m) { #if UPB_FASTTABLE - if (layout && layout->table_mask != (unsigned char)-1) { + if (m && m->UPB_PRIVATE(table_mask) != (unsigned char)-1) { uint16_t tag = _upb_FastDecoder_LoadTag(*ptr); - intptr_t table = decode_totable(layout); + intptr_t table = decode_totable(m); *ptr = _upb_FastDecoder_TagDispatch(d, *ptr, msg, table, 0, tag); return true; } @@ -12172,9 +12932,11 @@ static void upb_Decoder_AddKnownMessageSetItem( _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } upb_Message* submsg = _upb_Decoder_NewSubMessage( - d, &ext->ext->sub, &ext->ext->field, (upb_TaggedMessagePtr*)&ext->data); - upb_DecodeStatus status = upb_Decode(data, size, submsg, item_mt->sub.submsg, - d->extreg, d->options, &d->arena); + d, &ext->ext->UPB_PRIVATE(sub), upb_MiniTableExtension_AsField(ext->ext), + (upb_TaggedMessagePtr*)&ext->data); + upb_DecodeStatus status = upb_Decode( + data, size, submsg, upb_MiniTableExtension_GetSubMessage(item_mt), + d->extreg, d->options, &d->arena); if (status != kUpb_DecodeStatus_Ok) _upb_Decoder_ErrorJmp(d, status); } @@ -12195,9 +12957,11 @@ static void upb_Decoder_AddUnknownMessageSetItem(upb_Decoder* d, ptr = upb_Decoder_EncodeVarint32(kEndItemTag, ptr); char* end = ptr; - if (!_upb_Message_AddUnknown(msg, buf, split - buf, &d->arena) || - !_upb_Message_AddUnknown(msg, message_data, message_size, &d->arena) || - !_upb_Message_AddUnknown(msg, split, end - split, &d->arena)) { + if (!UPB_PRIVATE(_upb_Message_AddUnknown)(msg, buf, split - buf, &d->arena) || + !UPB_PRIVATE(_upb_Message_AddUnknown)(msg, message_data, message_size, + &d->arena) || + !UPB_PRIVATE(_upb_Message_AddUnknown)(msg, split, end - split, + &d->arena)) { _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } } @@ -12277,34 +13041,34 @@ static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d, if (t == NULL) return &none; size_t idx = ((size_t)field_number) - 1; // 0 wraps to SIZE_MAX - if (idx < t->dense_below) { + if (idx < t->UPB_PRIVATE(dense_below)) { /* Fastest case: index into dense fields. */ goto found; } - if (t->dense_below < t->field_count) { + if (t->UPB_PRIVATE(dense_below) < t->UPB_PRIVATE(field_count)) { /* Linear search non-dense fields. Resume scanning from last_field_index * since fields are usually in order. */ size_t last = *last_field_index; - for (idx = last; idx < t->field_count; idx++) { - if (t->fields[idx].number == field_number) { + for (idx = last; idx < t->UPB_PRIVATE(field_count); idx++) { + if (t->UPB_PRIVATE(fields)[idx].UPB_PRIVATE(number) == field_number) { goto found; } } - for (idx = t->dense_below; idx < last; idx++) { - if (t->fields[idx].number == field_number) { + for (idx = t->UPB_PRIVATE(dense_below); idx < last; idx++) { + if (t->UPB_PRIVATE(fields)[idx].UPB_PRIVATE(number) == field_number) { goto found; } } } if (d->extreg) { - switch (t->ext) { + switch (t->UPB_PRIVATE(ext)) { case kUpb_ExtMode_Extendable: { const upb_MiniTableExtension* ext = upb_ExtensionRegistry_Lookup(d->extreg, t, field_number); - if (ext) return &ext->field; + if (ext) return upb_MiniTableExtension_AsField(ext); break; } case kUpb_ExtMode_IsMessageSet: @@ -12320,9 +13084,9 @@ static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d, return &none; /* Unknown field. */ found: - UPB_ASSERT(t->fields[idx].number == field_number); + UPB_ASSERT(t->UPB_PRIVATE(fields)[idx].UPB_PRIVATE(number) == field_number); *last_field_index = idx; - return &t->fields[idx]; + return &t->UPB_PRIVATE(fields)[idx]; } int _upb_Decoder_GetVarintOp(const upb_MiniTableField* field) { @@ -12357,10 +13121,11 @@ static void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt, const upb_MiniTableField* field, int* op) { // If sub-message is not linked, treat as unknown. - if (field->mode & kUpb_LabelFlags_IsExtension) return; - const upb_MiniTableSub* sub = &mt->subs[field->UPB_PRIVATE(submsg_index)]; + if (field->UPB_PRIVATE(mode) & kUpb_LabelFlags_IsExtension) return; + const upb_MiniTable* mt_sub = + _upb_MiniTableSubs_MessageByField(mt->UPB_PRIVATE(subs), field); if ((d->options & kUpb_DecodeOption_ExperimentalAllowUnlinked) || - sub->submsg != &_kUpb_MiniTable_Empty) { + !UPB_PRIVATE(_upb_MiniTable_IsEmpty)(mt_sub)) { return; } #ifndef NDEBUG @@ -12371,7 +13136,7 @@ static void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt, do { UPB_ASSERT(upb_MiniTableField_CType(oneof) == kUpb_CType_Message); const upb_MiniTableSub* oneof_sub = - &mt->subs[oneof->UPB_PRIVATE(submsg_index)]; + &mt->UPB_PRIVATE(subs)[oneof->UPB_PRIVATE(submsg_index)]; UPB_ASSERT(!oneof_sub); } while (upb_MiniTable_NextOneofField(mt, &oneof)); } @@ -12430,7 +13195,7 @@ int _upb_Decoder_GetDelimitedOp(upb_Decoder* d, const upb_MiniTable* mt, }; int ndx = field->UPB_PRIVATE(descriptortype); - if (upb_FieldMode_Get(field) == kUpb_FieldMode_Array) ndx += kRepeatedBase; + if (upb_MiniTableField_IsArray(field)) ndx += kRepeatedBase; int op = kDelimitedOps[ndx]; if (op == kUpb_DecodeOp_SubMessage) { @@ -12477,7 +13242,7 @@ static const char* _upb_Decoder_DecodeWireValue(upb_Decoder* d, const char* ptr, *op = _upb_Decoder_GetDelimitedOp(d, mt, field); return ptr; case kUpb_WireType_StartGroup: - val->uint32_val = field->number; + val->uint32_val = field->UPB_PRIVATE(number); if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group) { *op = kUpb_DecodeOp_SubMessage; _upb_Decoder_CheckUnlinked(d, mt, field, op); @@ -12499,8 +13264,8 @@ static const char* _upb_Decoder_DecodeKnownField( upb_Decoder* d, const char* ptr, upb_Message* msg, const upb_MiniTable* layout, const upb_MiniTableField* field, int op, wireval* val) { - const upb_MiniTableSub* subs = layout->subs; - uint8_t mode = field->mode; + const upb_MiniTableSub* subs = layout->UPB_PRIVATE(subs); + uint8_t mode = field->UPB_PRIVATE(mode); if (UPB_UNLIKELY(mode & kUpb_LabelFlags_IsExtension)) { const upb_MiniTableExtension* ext_layout = @@ -12512,7 +13277,7 @@ static const char* _upb_Decoder_DecodeKnownField( } d->unknown_msg = msg; msg = &ext->data; - subs = &ext->ext->sub; + subs = &ext->ext->UPB_PRIVATE(sub); } switch (mode & kUpb_FieldMode_Mask) { @@ -12581,7 +13346,8 @@ static const char* _upb_Decoder_DecodeUnknownField(upb_Decoder* d, start = d->unknown; d->unknown = NULL; } - if (!_upb_Message_AddUnknown(msg, start, ptr - start, &d->arena)) { + if (!UPB_PRIVATE(_upb_Message_AddUnknown)(msg, start, ptr - start, + &d->arena)) { _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } } else if (wire_type == kUpb_WireType_StartGroup) { @@ -12653,7 +13419,7 @@ static const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr, } } - return UPB_UNLIKELY(layout && layout->required_count) + return UPB_UNLIKELY(layout && layout->UPB_PRIVATE(required_count)) ? _upb_Decoder_CheckRequired(d, ptr, msg, layout) : ptr; } @@ -12789,9 +13555,9 @@ static const char* fastdecode_dispatch(UPB_PARSE_PARAMS) { switch (upb_EpsCopyInputStream_IsDoneStatus(&d->input, ptr, &overrun)) { case kUpb_IsDoneStatus_Done: *(uint32_t*)msg |= hasbits; // Sync hasbits. - const upb_MiniTable* l = decode_totablep(table); - return UPB_UNLIKELY(l->required_count) - ? _upb_Decoder_CheckRequired(d, ptr, msg, l) + const upb_MiniTable* m = decode_totablep(table); + return UPB_UNLIKELY(m->UPB_PRIVATE(required_count)) + ? _upb_Decoder_CheckRequired(d, ptr, msg, m) : ptr; case kUpb_IsDoneStatus_NotDone: break; @@ -12891,17 +13657,17 @@ UPB_FORCEINLINE static void* fastdecode_resizearr(upb_Decoder* d, void* dst, fastdecode_arr* farr, int valbytes) { if (UPB_UNLIKELY(dst == farr->end)) { - size_t old_size = farr->arr->capacity; - size_t old_bytes = old_size * valbytes; - size_t new_size = old_size * 2; - size_t new_bytes = new_size * valbytes; + size_t old_capacity = farr->arr->UPB_PRIVATE(capacity); + size_t old_bytes = old_capacity * valbytes; + size_t new_capacity = old_capacity * 2; + size_t new_bytes = new_capacity * valbytes; char* old_ptr = _upb_array_ptr(farr->arr); char* new_ptr = upb_Arena_Realloc(&d->arena, old_ptr, old_bytes, new_bytes); uint8_t elem_size_lg2 = __builtin_ctz(valbytes); - farr->arr->capacity = new_size; - farr->arr->data = _upb_array_tagptr(new_ptr, elem_size_lg2); - dst = (void*)(new_ptr + (old_size * valbytes)); - farr->end = (void*)(new_ptr + (new_size * valbytes)); + UPB_PRIVATE(_upb_Array_SetTaggedPtr)(farr->arr, new_ptr, elem_size_lg2); + farr->arr->UPB_PRIVATE(capacity) = new_capacity; + dst = (void*)(new_ptr + (old_capacity * valbytes)); + farr->end = (void*)(new_ptr + (new_capacity * valbytes)); } return dst; } @@ -12981,13 +13747,13 @@ static void* fastdecode_getfield(upb_Decoder* d, const char* ptr, *(uint32_t*)msg |= *hasbits; *hasbits = 0; if (UPB_LIKELY(!*arr_p)) { - farr->arr = _upb_Array_New(&d->arena, 8, elem_size_lg2); + farr->arr = UPB_PRIVATE(_upb_Array_New)(&d->arena, 8, elem_size_lg2); *arr_p = farr->arr; } else { farr->arr = *arr_p; } begin = _upb_array_ptr(farr->arr); - farr->end = begin + (farr->arr->capacity * valbytes); + farr->end = begin + (farr->arr->UPB_PRIVATE(capacity) * valbytes); *data = _upb_FastDecoder_LoadTag(ptr); return begin + (farr->arr->size * valbytes); } @@ -13266,7 +14032,8 @@ TAGBYTES(p) int elems = size / valbytes; \ \ if (UPB_LIKELY(!arr)) { \ - *arr_p = arr = _upb_Array_New(&d->arena, elems, elem_size_lg2); \ + *arr_p = arr = \ + UPB_PRIVATE(_upb_Array_New)(&d->arena, elems, elem_size_lg2); \ if (!arr) { \ _upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed); \ } \ @@ -13384,12 +14151,14 @@ static const char* fastdecode_longstring_noutf8( UPB_FORCEINLINE static void fastdecode_docopy(upb_Decoder* d, const char* ptr, uint32_t size, - int copy, char* data, upb_StringView* dst) { + int copy, char* data, size_t data_offset, + upb_StringView* dst) { d->arena.head.ptr += copy; - dst->data = data; + dst->data = data + data_offset; UPB_UNPOISON_MEMORY_REGION(data, copy); memcpy(data, ptr, copy); - UPB_POISON_MEMORY_REGION(data + size, copy - size); + UPB_POISON_MEMORY_REGION(data + data_offset + size, + copy - data_offset - size); } #define FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \ @@ -13423,18 +14192,17 @@ static void fastdecode_docopy(upb_Decoder* d, const char* ptr, uint32_t size, \ if (UPB_LIKELY(size <= 15 - tagbytes)) { \ if (arena_has < 16) goto longstr; \ - d->arena.head.ptr += 16; \ - memcpy(buf, ptr - tagbytes - 1, 16); \ - dst->data = buf + tagbytes + 1; \ + fastdecode_docopy(d, ptr - tagbytes - 1, size, 16, buf, tagbytes + 1, \ + dst); \ } else if (UPB_LIKELY(size <= 32)) { \ if (UPB_UNLIKELY(common_has < 32)) goto longstr; \ - fastdecode_docopy(d, ptr, size, 32, buf, dst); \ + fastdecode_docopy(d, ptr, size, 32, buf, 0, dst); \ } else if (UPB_LIKELY(size <= 64)) { \ if (UPB_UNLIKELY(common_has < 64)) goto longstr; \ - fastdecode_docopy(d, ptr, size, 64, buf, dst); \ + fastdecode_docopy(d, ptr, size, 64, buf, 0, dst); \ } else if (UPB_LIKELY(size < 128)) { \ if (UPB_UNLIKELY(common_has < 128)) goto longstr; \ - fastdecode_docopy(d, ptr, size, 128, buf, dst); \ + fastdecode_docopy(d, ptr, size, 128, buf, 0, dst); \ } else { \ goto longstr; \ } \ @@ -13590,9 +14358,9 @@ TAGBYTES(r) /* message fields *************************************************************/ UPB_INLINE -upb_Message* decode_newmsg_ceil(upb_Decoder* d, const upb_MiniTable* l, +upb_Message* decode_newmsg_ceil(upb_Decoder* d, const upb_MiniTable* m, int msg_ceil_bytes) { - size_t size = l->size + sizeof(upb_Message_Internal); + size_t size = m->UPB_PRIVATE(size) + sizeof(upb_Message_Internal); char* msg_data; if (UPB_LIKELY(msg_ceil_bytes > 0 && _upb_ArenaHas(&d->arena) >= msg_ceil_bytes)) { @@ -13638,11 +14406,13 @@ static const char* fastdecode_tosubmsg(upb_EpsCopyInputStream* e, upb_Message** dst; \ uint32_t submsg_idx = (data >> 16) & 0xff; \ const upb_MiniTable* tablep = decode_totablep(table); \ - const upb_MiniTable* subtablep = tablep->subs[submsg_idx].submsg; \ + const upb_MiniTable* subtablep = upb_MiniTableSub_Message( \ + *UPB_PRIVATE(_upb_MiniTable_GetSubByIndex)(tablep, submsg_idx)); \ fastdecode_submsgdata submsg = {decode_totable(subtablep)}; \ fastdecode_arr farr; \ \ - if (subtablep->table_mask == (uint8_t)-1) { \ + if (subtablep->UPB_PRIVATE(table_mask) == (uint8_t)-1) { \ + d->depth++; \ RETURN_GENERIC("submessage doesn't have fast tables."); \ } \ \ @@ -13906,7 +14676,7 @@ static void encode_TaggedMessagePtr(upb_encstate* e, upb_TaggedMessagePtr tagged, const upb_MiniTable* m, size_t* size) { if (upb_TaggedMessagePtr_IsEmpty(tagged)) { - m = &_kUpb_MiniTable_Empty; + m = UPB_PRIVATE(_upb_MiniTable_Empty)(); } encode_message(e, _upb_TaggedMessagePtr_GetMessage(tagged), m, size); } @@ -13961,12 +14731,13 @@ static void encode_scalar(upb_encstate* e, const void* _field_mem, case kUpb_FieldType_Group: { size_t size; upb_TaggedMessagePtr submsg = *(upb_TaggedMessagePtr*)field_mem; - const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subm = + upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); if (submsg == 0) { return; } if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded); - encode_tag(e, f->number, kUpb_WireType_EndGroup); + encode_tag(e, f->UPB_PRIVATE(number), kUpb_WireType_EndGroup); encode_TaggedMessagePtr(e, submsg, subm, &size); wire_type = kUpb_WireType_StartGroup; e->depth++; @@ -13975,7 +14746,8 @@ static void encode_scalar(upb_encstate* e, const void* _field_mem, case kUpb_FieldType_Message: { size_t size; upb_TaggedMessagePtr submsg = *(upb_TaggedMessagePtr*)field_mem; - const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subm = + upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); if (submsg == 0) { return; } @@ -13991,34 +14763,35 @@ static void encode_scalar(upb_encstate* e, const void* _field_mem, } #undef CASE - encode_tag(e, f->number, wire_type); + encode_tag(e, f->UPB_PRIVATE(number), wire_type); } static void encode_array(upb_encstate* e, const upb_Message* msg, const upb_MiniTableSub* subs, const upb_MiniTableField* f) { const upb_Array* arr = *UPB_PTR_AT(msg, f->offset, upb_Array*); - bool packed = f->mode & kUpb_LabelFlags_IsPacked; + bool packed = upb_MiniTableField_IsPacked(f); size_t pre_len = e->limit - e->ptr; if (arr == NULL || arr->size == 0) { return; } -#define VARINT_CASE(ctype, encode) \ - { \ - const ctype* start = _upb_array_constptr(arr); \ - const ctype* ptr = start + arr->size; \ - uint32_t tag = packed ? 0 : (f->number << 3) | kUpb_WireType_Varint; \ - do { \ - ptr--; \ - encode_varint(e, encode); \ - if (tag) encode_varint(e, tag); \ - } while (ptr != start); \ - } \ +#define VARINT_CASE(ctype, encode) \ + { \ + const ctype* start = _upb_array_constptr(arr); \ + const ctype* ptr = start + arr->size; \ + uint32_t tag = \ + packed ? 0 : (f->UPB_PRIVATE(number) << 3) | kUpb_WireType_Varint; \ + do { \ + ptr--; \ + encode_varint(e, encode); \ + if (tag) encode_varint(e, tag); \ + } while (ptr != start); \ + } \ break; -#define TAG(wire_type) (packed ? 0 : (f->number << 3 | wire_type)) +#define TAG(wire_type) (packed ? 0 : (f->UPB_PRIVATE(number) << 3 | wire_type)) switch (f->UPB_PRIVATE(descriptortype)) { case kUpb_FieldType_Double: @@ -14057,21 +14830,22 @@ static void encode_array(upb_encstate* e, const upb_Message* msg, ptr--; encode_bytes(e, ptr->data, ptr->size); encode_varint(e, ptr->size); - encode_tag(e, f->number, kUpb_WireType_Delimited); + encode_tag(e, f->UPB_PRIVATE(number), kUpb_WireType_Delimited); } while (ptr != start); return; } case kUpb_FieldType_Group: { const upb_TaggedMessagePtr* start = _upb_array_constptr(arr); const upb_TaggedMessagePtr* ptr = start + arr->size; - const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subm = + upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded); do { size_t size; ptr--; - encode_tag(e, f->number, kUpb_WireType_EndGroup); + encode_tag(e, f->UPB_PRIVATE(number), kUpb_WireType_EndGroup); encode_TaggedMessagePtr(e, *ptr, subm, &size); - encode_tag(e, f->number, kUpb_WireType_StartGroup); + encode_tag(e, f->UPB_PRIVATE(number), kUpb_WireType_StartGroup); } while (ptr != start); e->depth++; return; @@ -14079,14 +14853,15 @@ static void encode_array(upb_encstate* e, const upb_Message* msg, case kUpb_FieldType_Message: { const upb_TaggedMessagePtr* start = _upb_array_constptr(arr); const upb_TaggedMessagePtr* ptr = start + arr->size; - const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subm = + upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded); do { size_t size; ptr--; encode_TaggedMessagePtr(e, *ptr, subm, &size); encode_varint(e, size); - encode_tag(e, f->number, kUpb_WireType_Delimited); + encode_tag(e, f->UPB_PRIVATE(number), kUpb_WireType_Delimited); } while (ptr != start); e->depth++; return; @@ -14096,19 +14871,19 @@ static void encode_array(upb_encstate* e, const upb_Message* msg, if (packed) { encode_varint(e, e->limit - e->ptr - pre_len); - encode_tag(e, f->number, kUpb_WireType_Delimited); + encode_tag(e, f->UPB_PRIVATE(number), kUpb_WireType_Delimited); } } static void encode_mapentry(upb_encstate* e, uint32_t number, const upb_MiniTable* layout, const upb_MapEntry* ent) { - const upb_MiniTableField* key_field = &layout->fields[0]; - const upb_MiniTableField* val_field = &layout->fields[1]; + const upb_MiniTableField* key_field = &layout->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* val_field = &layout->UPB_PRIVATE(fields)[1]; size_t pre_len = e->limit - e->ptr; size_t size; - encode_scalar(e, &ent->data.v, layout->subs, val_field); - encode_scalar(e, &ent->data.k, layout->subs, key_field); + encode_scalar(e, &ent->data.v, layout->UPB_PRIVATE(subs), val_field); + encode_scalar(e, &ent->data.k, layout->UPB_PRIVATE(subs), key_field); size = (e->limit - e->ptr) - pre_len; encode_varint(e, size); encode_tag(e, number, kUpb_WireType_Delimited); @@ -14118,19 +14893,20 @@ static void encode_map(upb_encstate* e, const upb_Message* msg, const upb_MiniTableSub* subs, const upb_MiniTableField* f) { const upb_Map* map = *UPB_PTR_AT(msg, f->offset, const upb_Map*); - const upb_MiniTable* layout = subs[f->UPB_PRIVATE(submsg_index)].submsg; - UPB_ASSERT(layout->field_count == 2); + const upb_MiniTable* layout = + upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); + UPB_ASSERT(layout->UPB_PRIVATE(field_count) == 2); if (map == NULL) return; if (e->options & kUpb_EncodeOption_Deterministic) { _upb_sortedmap sorted; - _upb_mapsorter_pushmap(&e->sorter, - layout->fields[0].UPB_PRIVATE(descriptortype), map, - &sorted); + _upb_mapsorter_pushmap( + &e->sorter, layout->UPB_PRIVATE(fields)[0].UPB_PRIVATE(descriptortype), + map, &sorted); upb_MapEntry ent; while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) { - encode_mapentry(e, f->number, layout, &ent); + encode_mapentry(e, f->UPB_PRIVATE(number), layout, &ent); } _upb_mapsorter_popmap(&e->sorter, &sorted); } else { @@ -14141,7 +14917,7 @@ static void encode_map(upb_encstate* e, const upb_Message* msg, upb_MapEntry ent; _upb_map_fromkey(key, &ent.data.k, map->key_size); _upb_map_fromvalue(val, &ent.data.v, map->val_size); - encode_mapentry(e, f->number, layout, &ent); + encode_mapentry(e, f->UPB_PRIVATE(number), layout, &ent); } } } @@ -14150,9 +14926,9 @@ static bool encode_shouldencode(upb_encstate* e, const upb_Message* msg, const upb_MiniTableSub* subs, const upb_MiniTableField* f) { if (f->presence == 0) { - /* Proto3 presence or map/array. */ + // Proto3 presence or map/array. const void* mem = UPB_PTR_AT(msg, f->offset, void); - switch (_upb_MiniTableField_GetRep(f)) { + switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(f)) { case kUpb_FieldRep_1Byte: { char ch; memcpy(&ch, mem, 1); @@ -14176,18 +14952,19 @@ static bool encode_shouldencode(upb_encstate* e, const upb_Message* msg, UPB_UNREACHABLE(); } } else if (f->presence > 0) { - /* Proto2 presence: hasbit. */ - return _upb_hasbit_field(msg, f); + // Proto2 presence: hasbit. + return UPB_PRIVATE(_upb_Message_GetHasbit)(msg, f); } else { - /* Field is in a oneof. */ - return _upb_getoneofcase_field(msg, f) == f->number; + // Field is in a oneof. + return UPB_PRIVATE(_upb_Message_GetOneofCase)(msg, f) == + f->UPB_PRIVATE(number); } } static void encode_field(upb_encstate* e, const upb_Message* msg, const upb_MiniTableSub* subs, const upb_MiniTableField* field) { - switch (upb_FieldMode_Get(field)) { + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(field)) { case kUpb_FieldMode_Array: encode_array(e, msg, subs, field); break; @@ -14206,10 +14983,11 @@ static void encode_msgset_item(upb_encstate* e, const upb_Message_Extension* ext) { size_t size; encode_tag(e, kUpb_MsgSet_Item, kUpb_WireType_EndGroup); - encode_message(e, ext->data.ptr, ext->ext->sub.submsg, &size); + encode_message(e, ext->data.ptr, + upb_MiniTableExtension_GetSubMessage(ext->ext), &size); encode_varint(e, size); encode_tag(e, kUpb_MsgSet_Message, kUpb_WireType_Delimited); - encode_varint(e, ext->ext->field.number); + encode_varint(e, upb_MiniTableExtension_Number(ext->ext)); encode_tag(e, kUpb_MsgSet_TypeId, kUpb_WireType_Varint); encode_tag(e, kUpb_MsgSet_Item, kUpb_WireType_StartGroup); } @@ -14219,7 +14997,8 @@ static void encode_ext(upb_encstate* e, const upb_Message_Extension* ext, if (UPB_UNLIKELY(is_message_set)) { encode_msgset_item(e, ext); } else { - encode_field(e, &ext->data, &ext->ext->sub, &ext->ext->field); + encode_field(e, &ext->data, &ext->ext->UPB_PRIVATE(sub), + &ext->ext->UPB_PRIVATE(field)); } } @@ -14227,11 +15006,12 @@ static void encode_message(upb_encstate* e, const upb_Message* msg, const upb_MiniTable* m, size_t* size) { size_t pre_len = e->limit - e->ptr; - if ((e->options & kUpb_EncodeOption_CheckRequired) && m->required_count) { + if ((e->options & kUpb_EncodeOption_CheckRequired) && + m->UPB_PRIVATE(required_count)) { uint64_t msg_head; memcpy(&msg_head, msg, 8); msg_head = _upb_BigEndian_Swap64(msg_head); - if (upb_MiniTable_requiredmask(m) & ~msg_head) { + if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) { encode_err(e, kUpb_EncodeStatus_MissingRequired); } } @@ -14245,7 +15025,7 @@ static void encode_message(upb_encstate* e, const upb_Message* msg, } } - if (m->ext != kUpb_ExtMode_NonExtendable) { + if (m->UPB_PRIVATE(ext) != kUpb_ExtMode_NonExtendable) { /* Encode all extensions together. Unlike C++, we do not attempt to keep * these in field number order relative to normal fields or even to each * other. */ @@ -14256,25 +15036,26 @@ static void encode_message(upb_encstate* e, const upb_Message* msg, _upb_sortedmap sorted; _upb_mapsorter_pushexts(&e->sorter, ext, ext_count, &sorted); while (_upb_sortedmap_nextext(&e->sorter, &sorted, &ext)) { - encode_ext(e, ext, m->ext == kUpb_ExtMode_IsMessageSet); + encode_ext(e, ext, m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet); } _upb_mapsorter_popmap(&e->sorter, &sorted); } else { const upb_Message_Extension* end = ext + ext_count; for (; ext != end; ext++) { - encode_ext(e, ext, m->ext == kUpb_ExtMode_IsMessageSet); + encode_ext(e, ext, m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet); } } } } - if (m->field_count) { - const upb_MiniTableField* f = &m->fields[m->field_count]; - const upb_MiniTableField* first = &m->fields[0]; + if (m->UPB_PRIVATE(field_count)) { + const upb_MiniTableField* f = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; + const upb_MiniTableField* first = &m->UPB_PRIVATE(fields)[0]; while (f != first) { f--; - if (encode_shouldencode(e, msg, m->subs, f)) { - encode_field(e, msg, m->subs, f); + if (encode_shouldencode(e, msg, m->UPB_PRIVATE(subs), f)) { + encode_field(e, msg, m->UPB_PRIVATE(subs), f); } } } @@ -14410,7 +15191,9 @@ const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag, #undef UPB_GNUC_MIN #undef UPB_DESCRIPTOR_UPB_H_FILENAME #undef UPB_DESC +#undef UPB_DESC_MINITABLE #undef UPB_IS_GOOGLE3 #undef UPB_ATOMIC #undef UPB_USE_C11_ATOMICS #undef UPB_PRIVATE +#undef UPB_ONLYBITS diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h index 9393812f7e..b339a0364f 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.h +++ b/ruby/ext/google/protobuf_c/ruby-upb.h @@ -182,6 +182,12 @@ Error, UINTPTR_MAX is undefined #define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only +#ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY +#define UPB_ONLYBITS(x) x +#else +#define UPB_ONLYBITS(x) UPB_PRIVATE(x) +#endif + /* Configure whether fasttable is switched on or not. *************************/ #ifdef __has_attribute @@ -320,8 +326,13 @@ void __asan_unpoison_memory_region(void const volatile *addr, size_t size); #if defined(UPB_IS_GOOGLE3) && !defined(UPB_BOOTSTRAP_STAGE0) #define UPB_DESC(sym) proto2_##sym +#define UPB_DESC_MINITABLE(sym) &proto2__##sym##_msg_init +#elif defined(UPB_BOOTSTRAP_STAGE0) +#define UPB_DESC(sym) google_protobuf_##sym +#define UPB_DESC_MINITABLE(sym) google__protobuf__##sym##_msg_init() #else #define UPB_DESC(sym) google_protobuf_##sym +#define UPB_DESC_MINITABLE(sym) &google__protobuf__##sym##_msg_init #endif #ifndef UPB_BASE_STATUS_H_ @@ -370,6 +381,10 @@ void upb_Status_VAppendErrorFormat(upb_Status* status, const char* fmt, #ifndef UPB_MESSAGE_ACCESSORS_H_ #define UPB_MESSAGE_ACCESSORS_H_ +#include +#include +#include + #ifndef UPB_BASE_DESCRIPTOR_CONSTANTS_H_ #define UPB_BASE_DESCRIPTOR_CONSTANTS_H_ @@ -429,7 +444,34 @@ typedef enum { extern "C" { #endif -UPB_INLINE bool upb_FieldType_IsPackable(upb_FieldType type) { +// Convert from upb_FieldType to upb_CType +UPB_INLINE upb_CType upb_FieldType_CType(upb_FieldType field_type) { + static const upb_CType c_type[] = { + kUpb_CType_Double, // kUpb_FieldType_Double + kUpb_CType_Float, // kUpb_FieldType_Float + kUpb_CType_Int64, // kUpb_FieldType_Int64 + kUpb_CType_UInt64, // kUpb_FieldType_UInt64 + kUpb_CType_Int32, // kUpb_FieldType_Int32 + kUpb_CType_UInt64, // kUpb_FieldType_Fixed64 + kUpb_CType_UInt32, // kUpb_FieldType_Fixed32 + kUpb_CType_Bool, // kUpb_FieldType_Bool + kUpb_CType_String, // kUpb_FieldType_String + kUpb_CType_Message, // kUpb_FieldType_Group + kUpb_CType_Message, // kUpb_FieldType_Message + kUpb_CType_Bytes, // kUpb_FieldType_Bytes + kUpb_CType_UInt32, // kUpb_FieldType_UInt32 + kUpb_CType_Enum, // kUpb_FieldType_Enum + kUpb_CType_Int32, // kUpb_FieldType_SFixed32 + kUpb_CType_Int64, // kUpb_FieldType_SFixed64 + kUpb_CType_Int32, // kUpb_FieldType_SInt32 + kUpb_CType_Int64, // kUpb_FieldType_SInt64 + }; + + // -1 here because the enum is one-based but the table is zero-based. + return c_type[field_type - 1]; +} + +UPB_INLINE bool upb_FieldType_IsPackable(upb_FieldType field_type) { // clang-format off const unsigned kUnpackableTypes = (1 << kUpb_FieldType_String) | @@ -437,7 +479,7 @@ UPB_INLINE bool upb_FieldType_IsPackable(upb_FieldType type) { (1 << kUpb_FieldType_Message) | (1 << kUpb_FieldType_Group); // clang-format on - return (1 << type) & ~kUnpackableTypes; + return (1 << field_type) & ~kUnpackableTypes; } #ifdef __cplusplus @@ -446,13 +488,58 @@ UPB_INLINE bool upb_FieldType_IsPackable(upb_FieldType type) { #endif /* UPB_BASE_DESCRIPTOR_CONSTANTS_H_ */ +#ifndef UPB_BASE_STRING_VIEW_H_ +#define UPB_BASE_STRING_VIEW_H_ -#ifndef UPB_MESSAGE_ARRAY_H_ -#define UPB_MESSAGE_ARRAY_H_ +#include -#include +// Must be last. + +#define UPB_STRINGVIEW_INIT(ptr, len) \ + { ptr, len } + +#define UPB_STRINGVIEW_FORMAT "%.*s" +#define UPB_STRINGVIEW_ARGS(view) (int)(view).size, (view).data + +// LINT.IfChange(struct_definition) +typedef struct { + const char* data; + size_t size; +} upb_StringView; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE upb_StringView upb_StringView_FromDataAndSize(const char* data, + size_t size) { + upb_StringView ret; + ret.data = data; + ret.size = size; + return ret; +} + +UPB_INLINE upb_StringView upb_StringView_FromString(const char* data) { + return upb_StringView_FromDataAndSize(data, strlen(data)); +} + +UPB_INLINE bool upb_StringView_IsEqual(upb_StringView a, upb_StringView b) { + return (a.size == b.size) && (!a.size || !memcmp(a.data, b.data, a.size)); +} + +// LINT.ThenChange( +// GoogleInternalName0, +// //depot/google3/third_party/upb/bits/golang/accessor.go:map_go_string, +// //depot/google3/third_party/upb/bits/typescript/string_view.ts +// ) + +#ifdef __cplusplus +} /* extern "C" */ +#endif +#endif /* UPB_BASE_STRING_VIEW_H_ */ + /* upb_Arena is a specific allocator implementation that uses arena allocation. * The user provides an allocator that will be used to allocate the underlying * arena blocks. Arenas by nature do not require the individual allocations @@ -547,9 +634,11 @@ UPB_INLINE void upb_gfree(void* ptr) { upb_free(&upb_alloc_global, ptr); } typedef struct upb_Arena upb_Arena; +// LINT.IfChange(struct_definition) typedef struct { char *ptr, *end; } _upb_ArenaHead; +// LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/arena.ts) #ifdef __cplusplus extern "C" { @@ -646,6 +735,12 @@ UPB_API_INLINE upb_Arena* upb_Arena_New(void) { #endif /* UPB_MEM_ARENA_H_ */ +#ifndef UPB_MESSAGE_ARRAY_H_ +#define UPB_MESSAGE_ARRAY_H_ + +#include + + // Users should include array.h or map.h instead. // IWYU pragma: private, include "upb/message/array.h" @@ -654,58 +749,9 @@ UPB_API_INLINE upb_Arena* upb_Arena_New(void) { #include -#ifndef UPB_BASE_STRING_VIEW_H_ -#define UPB_BASE_STRING_VIEW_H_ - -#include - -// Must be last. - -#define UPB_STRINGVIEW_INIT(ptr, len) \ - { ptr, len } - -#define UPB_STRINGVIEW_FORMAT "%.*s" -#define UPB_STRINGVIEW_ARGS(view) (int)(view).size, (view).data - -// LINT.IfChange(struct_definition) -typedef struct { - const char* data; - size_t size; -} upb_StringView; -// LINT.ThenChange( -// GoogleInternalName0, -// //depot/google3/third_party/upb/bits/golang/accessor.go:map_go_string -// ) - -#ifdef __cplusplus -extern "C" { -#endif - -UPB_API_INLINE upb_StringView upb_StringView_FromDataAndSize(const char* data, - size_t size) { - upb_StringView ret; - ret.data = data; - ret.size = size; - return ret; -} - -UPB_INLINE upb_StringView upb_StringView_FromString(const char* data) { - return upb_StringView_FromDataAndSize(data, strlen(data)); -} - -UPB_INLINE bool upb_StringView_IsEqual(upb_StringView a, upb_StringView b) { - return a.size == b.size && memcmp(a.data, b.data, a.size) == 0; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* UPB_BASE_STRING_VIEW_H_ */ - -#ifndef UPB_MINI_TABLE_TYPES_H_ -#define UPB_MINI_TABLE_TYPES_H_ +#ifndef UPB_MINI_TABLE_TAGGED_PTR_H_ +#define UPB_MINI_TABLE_TAGGED_PTR_H_ #include @@ -721,10 +767,6 @@ typedef void upb_Message; // Must be last. -#ifdef __cplusplus -extern "C" { -#endif - // When a upb_Message* is stored in a message, array, or map, it is stored in a // tagged form. If the tag bit is set, the referenced upb_Message is of type // _kUpb_MiniTable_Empty (a sentinel message type with no fields) instead of @@ -733,8 +775,13 @@ extern "C" { // // See the documentation for kUpb_DecodeOption_ExperimentalAllowUnlinked for // more information. + typedef uintptr_t upb_TaggedMessagePtr; +#ifdef __cplusplus +extern "C" { +#endif + // Internal-only because empty messages cannot be created by the user. UPB_INLINE upb_TaggedMessagePtr _upb_TaggedMessagePtr_Pack(upb_Message* ptr, bool empty) { @@ -771,7 +818,7 @@ UPB_INLINE upb_Message* _upb_TaggedMessagePtr_GetEmptyMessage( #endif -#endif /* UPB_MINI_TABLE_TYPES_H_ */ +#endif /* UPB_MINI_TABLE_TAGGED_PTR_H_ */ typedef union { bool bool_val; @@ -862,6 +909,10 @@ UPB_API void* upb_Array_MutableDataPtr(upb_Array* arr); #ifndef UPB_MESSAGE_INTERNAL_ACCESSORS_H_ #define UPB_MESSAGE_INTERNAL_ACCESSORS_H_ +#include +#include +#include + #ifndef UPB_MESSAGE_INTERNAL_EXTENSION_H_ #define UPB_MESSAGE_INTERNAL_EXTENSION_H_ @@ -884,6 +935,8 @@ UPB_API void* upb_Array_MutableDataPtr(upb_Array* arr); #ifndef UPB_MINI_TABLE_ENUM_H_ #define UPB_MINI_TABLE_ENUM_H_ +#include + #ifndef UPB_MINI_TABLE_INTERNAL_ENUM_H_ #define UPB_MINI_TABLE_INTERNAL_ENUM_H_ @@ -893,35 +946,34 @@ UPB_API void* upb_Array_MutableDataPtr(upb_Array* arr); // Must be last. struct upb_MiniTableEnum { - uint32_t mask_limit; // Limit enum value that can be tested with mask. - uint32_t value_count; // Number of values after the bitfield. - uint32_t data[]; // Bitmask + enumerated values follow. + uint32_t UPB_PRIVATE(mask_limit); // Highest that can be tested with mask. + uint32_t UPB_PRIVATE(value_count); // Number of values after the bitfield. + uint32_t UPB_PRIVATE(data)[]; // Bitmask + enumerated values follow. }; -typedef enum { - _kUpb_FastEnumCheck_ValueIsInEnum = 0, - _kUpb_FastEnumCheck_ValueIsNotInEnum = 1, - _kUpb_FastEnumCheck_CannotCheckFast = 2, -} _kUpb_FastEnumCheck_Status; - #ifdef __cplusplus extern "C" { #endif -UPB_INLINE _kUpb_FastEnumCheck_Status _upb_MiniTable_CheckEnumValueFast( +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableEnum_CheckValue)( const struct upb_MiniTableEnum* e, uint32_t val) { - if (UPB_UNLIKELY(val >= 64)) return _kUpb_FastEnumCheck_CannotCheckFast; - uint64_t mask = e->data[0] | ((uint64_t)e->data[1] << 32); - return (mask & (1ULL << val)) ? _kUpb_FastEnumCheck_ValueIsInEnum - : _kUpb_FastEnumCheck_ValueIsNotInEnum; -} + if (UPB_LIKELY(val < 64)) { + const uint64_t mask = + e->UPB_PRIVATE(data)[0] | ((uint64_t)e->UPB_PRIVATE(data)[1] << 32); + const uint64_t bit = 1ULL << val; + return (mask & bit) != 0; + } + if (UPB_LIKELY(val < e->UPB_PRIVATE(mask_limit))) { + const uint32_t mask = e->UPB_PRIVATE(data)[val / 32]; + const uint32_t bit = 1ULL << (val % 32); + return (mask & bit) != 0; + } -UPB_INLINE bool _upb_MiniTable_CheckEnumValueSlow( - const struct upb_MiniTableEnum* e, uint32_t val) { - if (val < e->mask_limit) return e->data[val / 32] & (1ULL << (val % 32)); // OPT: binary search long lists? - const uint32_t* start = &e->data[e->mask_limit / 32]; - const uint32_t* limit = &e->data[(e->mask_limit / 32) + e->value_count]; + const uint32_t* start = + &e->UPB_PRIVATE(data)[e->UPB_PRIVATE(mask_limit) / 32]; + const uint32_t* limit = &e->UPB_PRIVATE( + data)[e->UPB_PRIVATE(mask_limit) / 32 + e->UPB_PRIVATE(value_count)]; for (const uint32_t* p = start; p < limit; p++) { if (*p == val) return true; } @@ -944,13 +996,9 @@ extern "C" { #endif // Validates enum value against range defined by enum mini table. -UPB_INLINE bool upb_MiniTableEnum_CheckValue(const struct upb_MiniTableEnum* e, +UPB_INLINE bool upb_MiniTableEnum_CheckValue(const upb_MiniTableEnum* e, uint32_t val) { - _kUpb_FastEnumCheck_Status status = _upb_MiniTable_CheckEnumValueFast(e, val); - if (UPB_UNLIKELY(status == _kUpb_FastEnumCheck_CannotCheckFast)) { - return _upb_MiniTable_CheckEnumValueSlow(e, val); - } - return status == _kUpb_FastEnumCheck_ValueIsInEnum ? true : false; + return UPB_PRIVATE(_upb_MiniTableEnum_CheckValue)(e, val); } #ifdef __cplusplus @@ -963,19 +1011,90 @@ UPB_INLINE bool upb_MiniTableEnum_CheckValue(const struct upb_MiniTableEnum* e, #ifndef UPB_MINI_TABLE_FIELD_H_ #define UPB_MINI_TABLE_FIELD_H_ +#include + #ifndef UPB_MINI_TABLE_INTERNAL_FIELD_H_ #define UPB_MINI_TABLE_INTERNAL_FIELD_H_ +#include +#include + + +#ifndef UPB_MINI_TABLE_INTERNAL_SIZE_LOG2_H_ +#define UPB_MINI_TABLE_INTERNAL_SIZE_LOG2_H_ + +#include #include // Must be last. +#ifdef __cplusplus +extern "C" { +#endif + +// Return the log2 of the storage size in bytes for a upb_CType +UPB_INLINE int upb_CType_SizeLg2(upb_CType c_type) { + static const int8_t size[] = { + 0, // kUpb_CType_Bool + 2, // kUpb_CType_Float + 2, // kUpb_CType_Int32 + 2, // kUpb_CType_UInt32 + 2, // kUpb_CType_Enum + UPB_SIZE(2, 3), // kUpb_CType_Message + 3, // kUpb_CType_Double + 3, // kUpb_CType_Int64 + 3, // kUpb_CType_UInt64 + UPB_SIZE(3, 4), // kUpb_CType_String + UPB_SIZE(3, 4), // kUpb_CType_Bytes + }; + + // -1 here because the enum is one-based but the table is zero-based. + return size[c_type - 1]; +} + +// Return the log2 of the storage size in bytes for a upb_FieldType +UPB_INLINE int upb_FieldType_SizeLg2(upb_FieldType field_type) { + static const int8_t size[] = { + 3, // kUpb_FieldType_Double + 2, // kUpb_FieldType_Float + 3, // kUpb_FieldType_Int64 + 3, // kUpb_FieldType_UInt64 + 2, // kUpb_FieldType_Int32 + 3, // kUpb_FieldType_Fixed64 + 2, // kUpb_FieldType_Fixed32 + 0, // kUpb_FieldType_Bool + UPB_SIZE(3, 4), // kUpb_FieldType_String + UPB_SIZE(2, 3), // kUpb_FieldType_Group + UPB_SIZE(2, 3), // kUpb_FieldType_Message + UPB_SIZE(3, 4), // kUpb_FieldType_Bytes + 2, // kUpb_FieldType_UInt32 + 2, // kUpb_FieldType_Enum + 2, // kUpb_FieldType_SFixed32 + 3, // kUpb_FieldType_SFixed64 + 2, // kUpb_FieldType_SInt32 + 3, // kUpb_FieldType_SInt64 + }; + + // -1 here because the enum is one-based but the table is zero-based. + return size[field_type - 1]; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_SIZE_LOG2_H_ */ + +// Must be last. + +// LINT.IfChange(struct_definition) struct upb_MiniTableField { - uint32_t number; + uint32_t UPB_ONLYBITS(number); uint16_t offset; - int16_t presence; // If >0, hasbit_index. If <0, ~oneof_index + int16_t presence; // If >0, hasbit_index. If <0, ~oneof_index // Indexes into `upb_MiniTable.subs` // Will be set to `kUpb_NoSub` if `descriptortype` != MESSAGE/GROUP/ENUM @@ -984,7 +1103,7 @@ struct upb_MiniTableField { uint8_t UPB_PRIVATE(descriptortype); // upb_FieldMode | upb_LabelFlags | (upb_FieldRep << kUpb_FieldRep_Shift) - uint8_t mode; + uint8_t UPB_ONLYBITS(mode); }; #define kUpb_NoSub ((uint16_t)-1) @@ -1024,213 +1143,205 @@ typedef enum { #define kUpb_FieldRep_Shift 6 -UPB_INLINE upb_FieldRep -_upb_MiniTableField_GetRep(const struct upb_MiniTableField* field) { - return (upb_FieldRep)(field->mode >> kUpb_FieldRep_Shift); -} - #ifdef __cplusplus extern "C" { #endif UPB_INLINE upb_FieldMode -upb_FieldMode_Get(const struct upb_MiniTableField* field) { - return (upb_FieldMode)(field->mode & 3); +UPB_PRIVATE(_upb_MiniTableField_Mode)(const struct upb_MiniTableField* f) { + return (upb_FieldMode)(f->UPB_ONLYBITS(mode) & kUpb_FieldMode_Mask); } -UPB_INLINE void _upb_MiniTableField_CheckIsArray( - const struct upb_MiniTableField* field) { - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_NativePointer); - UPB_ASSUME(upb_FieldMode_Get(field) == kUpb_FieldMode_Array); - UPB_ASSUME(field->presence == 0); +UPB_INLINE upb_FieldRep +UPB_PRIVATE(_upb_MiniTableField_GetRep)(const struct upb_MiniTableField* f) { + return (upb_FieldRep)(f->UPB_ONLYBITS(mode) >> kUpb_FieldRep_Shift); } -UPB_INLINE void _upb_MiniTableField_CheckIsMap( - const struct upb_MiniTableField* field) { - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_NativePointer); - UPB_ASSUME(upb_FieldMode_Get(field) == kUpb_FieldMode_Map); - UPB_ASSUME(field->presence == 0); +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsArray)( + const struct upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_Mode)(f) == kUpb_FieldMode_Array; } -UPB_INLINE bool upb_IsRepeatedOrMap(const struct upb_MiniTableField* field) { - // This works because upb_FieldMode has no value 3. - return !(field->mode & kUpb_FieldMode_Scalar); +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsMap)( + const struct upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_Mode)(f) == kUpb_FieldMode_Map; } -UPB_INLINE bool upb_IsSubMessage(const struct upb_MiniTableField* field) { - return field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Message || - field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group; +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsScalar)( + const struct upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_Mode)(f) == kUpb_FieldMode_Scalar; } -#ifdef __cplusplus -} /* extern "C" */ -#endif - +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsAlternate)( + const struct upb_MiniTableField* f) { + return (f->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsAlternate) != 0; +} -#endif /* UPB_MINI_TABLE_INTERNAL_FIELD_H_ */ +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsExtension)( + const struct upb_MiniTableField* f) { + return (f->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsExtension) != 0; +} -#ifndef UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ -#define UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsPacked)( + const struct upb_MiniTableField* f) { + return (f->UPB_ONLYBITS(mode) & kUpb_LabelFlags_IsPacked) != 0; +} +UPB_INLINE upb_FieldType +UPB_PRIVATE(_upb_MiniTableField_Type)(const struct upb_MiniTableField* f) { + const upb_FieldType type = (upb_FieldType)f->UPB_PRIVATE(descriptortype); + if (UPB_PRIVATE(_upb_MiniTableField_IsAlternate)(f)) { + if (type == kUpb_FieldType_Int32) return kUpb_FieldType_Enum; + if (type == kUpb_FieldType_Bytes) return kUpb_FieldType_String; + UPB_ASSERT(false); + } + return type; +} -// Must be last. +UPB_INLINE upb_CType +UPB_PRIVATE(_upb_MiniTableField_CType)(const struct upb_MiniTableField* f) { + return upb_FieldType_CType(UPB_PRIVATE(_upb_MiniTableField_Type)(f)); +} -struct upb_Decoder; -typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr, - upb_Message* msg, intptr_t table, - uint64_t hasbits, uint64_t data); -typedef struct { - uint64_t field_data; - _upb_FieldParser* field_parser; -} _upb_FastTable_Entry; +UPB_INLINE char _upb_MiniTableField_HasbitMask( + const struct upb_MiniTableField* f) { + UPB_ASSERT(f->presence > 0); + const size_t index = f->presence; + return 1 << (index % 8); +} -typedef enum { - kUpb_ExtMode_NonExtendable = 0, // Non-extendable message. - kUpb_ExtMode_Extendable = 1, // Normal extendable message. - kUpb_ExtMode_IsMessageSet = 2, // MessageSet message. - kUpb_ExtMode_IsMessageSet_ITEM = - 3, // MessageSet item (temporary only, see decode.c) +UPB_INLINE size_t +_upb_MiniTableField_HasbitOffset(const struct upb_MiniTableField* f) { + UPB_ASSERT(f->presence > 0); + const size_t index = f->presence; + return index / 8; +} - // During table building we steal a bit to indicate that the message is a map - // entry. *Only* used during table building! - kUpb_ExtMode_IsMapEntry = 4, -} upb_ExtMode; +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsClosedEnum)( + const struct upb_MiniTableField* f) { + return f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum; +} -union upb_MiniTableSub; +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsInOneof)( + const struct upb_MiniTableField* f) { + return f->presence < 0; +} -// upb_MiniTable represents the memory layout of a given upb_MessageDef. -// The members are public so generated code can initialize them, -// but users MUST NOT directly read or write any of its members. -struct upb_MiniTable { - const union upb_MiniTableSub* subs; - const struct upb_MiniTableField* fields; +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_IsSubMessage)( + const struct upb_MiniTableField* f) { + return f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Message || + f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group; +} - // Must be aligned to sizeof(void*). Doesn't include internal members like - // unknown fields, extension dict, pointer to msglayout, etc. - uint16_t size; +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_HasPresence)( + const struct upb_MiniTableField* f) { + if (UPB_PRIVATE(_upb_MiniTableField_IsExtension)(f)) { + return UPB_PRIVATE(_upb_MiniTableField_IsScalar)(f); + } else { + return f->presence != 0; + } +} - uint16_t field_count; - uint8_t ext; // upb_ExtMode, declared as uint8_t so sizeof(ext) == 1 - uint8_t dense_below; - uint8_t table_mask; - uint8_t required_count; // Required fields have the lowest hasbits. +UPB_INLINE uint32_t +UPB_PRIVATE(_upb_MiniTableField_Number)(const struct upb_MiniTableField* f) { + return f->UPB_ONLYBITS(number); +} - // To statically initialize the tables of variable length, we need a flexible - // array member, and we need to compile in gnu99 mode (constant initialization - // of flexible array members is a GNU extension, not in C99 unfortunately. - _upb_FastTable_Entry fasttable[]; -}; +UPB_INLINE size_t +_upb_MiniTableField_OneofOffset(const struct upb_MiniTableField* f) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_IsInOneof)(f)); + return ~(ptrdiff_t)f->presence; +} -#ifdef __cplusplus -extern "C" { -#endif +UPB_INLINE void UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)( + const struct upb_MiniTableField* f) { + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == + kUpb_FieldRep_NativePointer); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_IsArray)(f)); + UPB_ASSUME(f->presence == 0); +} -// A MiniTable for an empty message, used for unlinked sub-messages. -extern const struct upb_MiniTable _kUpb_MiniTable_Empty; +UPB_INLINE void UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)( + const struct upb_MiniTableField* f) { + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(f) == + kUpb_FieldRep_NativePointer); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_IsMap)(f)); + UPB_ASSUME(f->presence == 0); +} -// Computes a bitmask in which the |l->required_count| lowest bits are set, -// except that we skip the lowest bit (because upb never uses hasbit 0). -// -// Sample output: -// requiredmask(1) => 0b10 (0x2) -// requiredmask(5) => 0b111110 (0x3e) -UPB_INLINE uint64_t upb_MiniTable_requiredmask(const struct upb_MiniTable* l) { - int n = l->required_count; - assert(0 < n && n <= 63); - return ((1ULL << n) - 1) << 1; +UPB_INLINE size_t UPB_PRIVATE(_upb_MiniTableField_ElemSizeLg2)( + const struct upb_MiniTableField* f) { + return upb_FieldType_SizeLg2((upb_FieldType)f->UPB_PRIVATE(descriptortype)); } +// LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/mini_table_field.ts) + #ifdef __cplusplus } /* extern "C" */ #endif -#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */ -#ifndef UPB_MINI_TABLE_INTERNAL_SUB_H_ -#define UPB_MINI_TABLE_INTERNAL_SUB_H_ - - -union upb_MiniTableSub { - const struct upb_MiniTable* submsg; - const struct upb_MiniTableEnum* subenum; -}; - -#endif /* UPB_MINI_TABLE_INTERNAL_SUB_H_ */ +#endif /* UPB_MINI_TABLE_INTERNAL_FIELD_H_ */ // Must be last. +typedef struct upb_MiniTableField upb_MiniTableField; + #ifdef __cplusplus extern "C" { #endif -typedef struct upb_MiniTableField upb_MiniTableField; +UPB_API_INLINE upb_CType upb_MiniTableField_CType(const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_CType)(f); +} -UPB_API_INLINE upb_FieldType -upb_MiniTableField_Type(const upb_MiniTableField* field) { - if (field->mode & kUpb_LabelFlags_IsAlternate) { - if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Int32) { - return kUpb_FieldType_Enum; - } else if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bytes) { - return kUpb_FieldType_String; - } else { - UPB_ASSERT(false); - } - } - return (upb_FieldType)field->UPB_PRIVATE(descriptortype); +UPB_API_INLINE bool upb_MiniTableField_HasPresence( + const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_HasPresence)(f); } -UPB_API_INLINE upb_CType upb_MiniTableField_CType(const upb_MiniTableField* f) { - switch (upb_MiniTableField_Type(f)) { - case kUpb_FieldType_Double: - return kUpb_CType_Double; - case kUpb_FieldType_Float: - return kUpb_CType_Float; - case kUpb_FieldType_Int64: - case kUpb_FieldType_SInt64: - case kUpb_FieldType_SFixed64: - return kUpb_CType_Int64; - case kUpb_FieldType_Int32: - case kUpb_FieldType_SFixed32: - case kUpb_FieldType_SInt32: - return kUpb_CType_Int32; - case kUpb_FieldType_UInt64: - case kUpb_FieldType_Fixed64: - return kUpb_CType_UInt64; - case kUpb_FieldType_UInt32: - case kUpb_FieldType_Fixed32: - return kUpb_CType_UInt32; - case kUpb_FieldType_Enum: - return kUpb_CType_Enum; - case kUpb_FieldType_Bool: - return kUpb_CType_Bool; - case kUpb_FieldType_String: - return kUpb_CType_String; - case kUpb_FieldType_Bytes: - return kUpb_CType_Bytes; - case kUpb_FieldType_Group: - case kUpb_FieldType_Message: - return kUpb_CType_Message; - } - UPB_UNREACHABLE(); +UPB_API_INLINE bool upb_MiniTableField_IsArray(const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_IsArray)(f); +} + +UPB_API_INLINE bool upb_MiniTableField_IsClosedEnum( + const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_IsClosedEnum)(f); } UPB_API_INLINE bool upb_MiniTableField_IsExtension( - const upb_MiniTableField* field) { - return field->mode & kUpb_LabelFlags_IsExtension; + const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_IsExtension)(f); } -UPB_API_INLINE bool upb_MiniTableField_IsClosedEnum( - const upb_MiniTableField* field) { - return field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum; +UPB_API_INLINE bool upb_MiniTableField_IsInOneof(const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_IsInOneof)(f); } -UPB_API_INLINE bool upb_MiniTableField_HasPresence( - const upb_MiniTableField* field) { - if (upb_MiniTableField_IsExtension(field)) { - return !upb_IsRepeatedOrMap(field); - } else { - return field->presence != 0; - } +UPB_API_INLINE bool upb_MiniTableField_IsMap(const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_IsMap)(f); +} + +UPB_API_INLINE bool upb_MiniTableField_IsPacked(const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_IsPacked)(f); +} + +UPB_API_INLINE bool upb_MiniTableField_IsScalar(const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_IsScalar)(f); +} + +UPB_API_INLINE bool upb_MiniTableField_IsSubMessage( + const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_IsSubMessage)(f); +} + +UPB_API_INLINE uint32_t upb_MiniTableField_Number(const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_Number)(f); +} + +UPB_API_INLINE upb_FieldType +upb_MiniTableField_Type(const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTableField_Type)(f); } #ifdef __cplusplus @@ -1240,46 +1351,246 @@ UPB_API_INLINE bool upb_MiniTableField_HasPresence( #endif /* UPB_MINI_TABLE_FIELD_H_ */ +#ifndef UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ +#define UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ + + +#ifndef UPB_MINI_TABLE_INTERNAL_SUB_H_ +#define UPB_MINI_TABLE_INTERNAL_SUB_H_ + +// Must be last. + +union upb_MiniTableSub { + const struct upb_MiniTable* UPB_PRIVATE(submsg); + const struct upb_MiniTableEnum* UPB_PRIVATE(subenum); +}; + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE union upb_MiniTableSub UPB_PRIVATE(_upb_MiniTableSub_FromEnum)( + const struct upb_MiniTableEnum* subenum) { + union upb_MiniTableSub out; + out.UPB_PRIVATE(subenum) = subenum; + return out; +} + +UPB_INLINE union upb_MiniTableSub UPB_PRIVATE(_upb_MiniTableSub_FromMessage)( + const struct upb_MiniTable* submsg) { + union upb_MiniTableSub out; + out.UPB_PRIVATE(submsg) = submsg; + return out; +} + +UPB_INLINE const struct upb_MiniTableEnum* UPB_PRIVATE(_upb_MiniTableSub_Enum)( + const union upb_MiniTableSub sub) { + return sub.UPB_PRIVATE(subenum); +} + +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTableSub_Message)( + const union upb_MiniTableSub sub) { + return sub.UPB_PRIVATE(submsg); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_SUB_H_ */ + // Must be last. +struct upb_Decoder; +typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr, + upb_Message* msg, intptr_t table, + uint64_t hasbits, uint64_t data); +typedef struct { + uint64_t field_data; + _upb_FieldParser* field_parser; +} _upb_FastTable_Entry; + +typedef enum { + kUpb_ExtMode_NonExtendable = 0, // Non-extendable message. + kUpb_ExtMode_Extendable = 1, // Normal extendable message. + kUpb_ExtMode_IsMessageSet = 2, // MessageSet message. + kUpb_ExtMode_IsMessageSet_ITEM = + 3, // MessageSet item (temporary only, see decode.c) + + // During table building we steal a bit to indicate that the message is a map + // entry. *Only* used during table building! + kUpb_ExtMode_IsMapEntry = 4, +} upb_ExtMode; + +// upb_MiniTable represents the memory layout of a given upb_MessageDef. +// The members are public so generated code can initialize them, +// but users MUST NOT directly read or write any of its members. +// LINT.IfChange(minitable_struct_definition) +struct upb_MiniTable { + const union upb_MiniTableSub* UPB_PRIVATE(subs); + const struct upb_MiniTableField* UPB_ONLYBITS(fields); + + // Must be aligned to sizeof(void*). Doesn't include internal members like + // unknown fields, extension dict, pointer to msglayout, etc. + uint16_t UPB_PRIVATE(size); + + uint16_t UPB_ONLYBITS(field_count); + + uint8_t UPB_PRIVATE(ext); // upb_ExtMode, uint8_t here so sizeof(ext) == 1 + uint8_t UPB_PRIVATE(dense_below); + uint8_t UPB_PRIVATE(table_mask); + uint8_t UPB_PRIVATE(required_count); // Required fields have the low hasbits. + + // To statically initialize the tables of variable length, we need a flexible + // array member, and we need to compile in gnu99 mode (constant initialization + // of flexible array members is a GNU extension, not in C99 unfortunately. + _upb_FastTable_Entry UPB_PRIVATE(fasttable)[]; +}; +// LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/mini_table.ts) + #ifdef __cplusplus extern "C" { #endif +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTable_Empty)(void) { + extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty); + + return &UPB_PRIVATE(_kUpb_MiniTable_Empty); +} + +UPB_INLINE int UPB_PRIVATE(_upb_MiniTable_FieldCount)( + const struct upb_MiniTable* m) { + return m->UPB_ONLYBITS(field_count); +} + +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_IsEmpty)( + const struct upb_MiniTable* m) { + extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty); + + return m == &UPB_PRIVATE(_kUpb_MiniTable_Empty); +} + +UPB_INLINE const struct upb_MiniTableField* UPB_PRIVATE( + _upb_MiniTable_GetFieldByIndex)(const struct upb_MiniTable* m, uint32_t i) { + return &m->UPB_ONLYBITS(fields)[i]; +} + +UPB_INLINE const union upb_MiniTableSub* UPB_PRIVATE( + _upb_MiniTable_GetSubByIndex)(const struct upb_MiniTable* m, uint32_t i) { + return &m->UPB_PRIVATE(subs)[i]; +} + +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE( + _upb_MiniTable_GetSubMessageTable)(const struct upb_MiniTable* m, + const struct upb_MiniTableField* f) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_CType)(f) == kUpb_CType_Message); + const struct upb_MiniTable* ret = UPB_PRIVATE(_upb_MiniTableSub_Message)( + m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); + UPB_ASSUME(ret); + return UPB_PRIVATE(_upb_MiniTable_IsEmpty)(ret) ? NULL : ret; +} + +UPB_INLINE const struct upb_MiniTableEnum* UPB_PRIVATE( + _upb_MiniTable_GetSubEnumTable)(const struct upb_MiniTable* m, + const struct upb_MiniTableField* f) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_CType)(f) == kUpb_CType_Enum); + return UPB_PRIVATE(_upb_MiniTableSub_Enum)( + m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); +} + +UPB_INLINE const struct upb_MiniTableField* UPB_PRIVATE(_upb_MiniTable_MapKey)( + const struct upb_MiniTable* m) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTable_FieldCount)(m) == 2); + const struct upb_MiniTableField* f = + UPB_PRIVATE(_upb_MiniTable_GetFieldByIndex)(m, 0); + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_Number)(f) == 1); + return f; +} + +UPB_INLINE const struct upb_MiniTableField* UPB_PRIVATE( + _upb_MiniTable_MapValue)(const struct upb_MiniTable* m) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTable_FieldCount)(m) == 2); + const struct upb_MiniTableField* f = + UPB_PRIVATE(_upb_MiniTable_GetFieldByIndex)(m, 1); + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_Number)(f) == 2); + return f; +} + +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_MessageFieldIsLinked)( + const struct upb_MiniTable* m, const struct upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTable_GetSubMessageTable)(m, f) != NULL; +} + +// Computes a bitmask in which the |m->required_count| lowest bits are set, +// except that we skip the lowest bit (because upb never uses hasbit 0). +// +// Sample output: +// RequiredMask(1) => 0b10 (0x2) +// RequiredMask(5) => 0b111110 (0x3e) +UPB_INLINE uint64_t +UPB_PRIVATE(_upb_MiniTable_RequiredMask)(const struct upb_MiniTable* m) { + int n = m->UPB_PRIVATE(required_count); + UPB_ASSERT(0 < n && n <= 63); + return ((1ULL << n) - 1) << 1; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */ + +// Must be last. + typedef struct upb_MiniTable upb_MiniTable; +#ifdef __cplusplus +extern "C" { +#endif + UPB_API const upb_MiniTableField* upb_MiniTable_FindFieldByNumber( - const upb_MiniTable* table, uint32_t number); + const upb_MiniTable* m, uint32_t number); UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_GetFieldByIndex( - const upb_MiniTable* t, uint32_t index) { - return &t->fields[index]; + const upb_MiniTable* m, uint32_t index) { + return UPB_PRIVATE(_upb_MiniTable_GetFieldByIndex)(m, index); } -// Returns the MiniTable for this message field. If the field is unlinked, -// returns NULL. +UPB_API_INLINE int upb_MiniTable_FieldCount(const upb_MiniTable* m) { + return UPB_PRIVATE(_upb_MiniTable_FieldCount)(m); +} + +// Returns the MiniTable for a message field, NULL if the field is unlinked. UPB_API_INLINE const upb_MiniTable* upb_MiniTable_GetSubMessageTable( - const upb_MiniTable* mini_table, const upb_MiniTableField* field) { - UPB_ASSERT(upb_MiniTableField_CType(field) == kUpb_CType_Message); - const upb_MiniTable* ret = - mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg; - UPB_ASSUME(ret); - return ret == &_kUpb_MiniTable_Empty ? NULL : ret; + const upb_MiniTable* m, const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTable_GetSubMessageTable)(m, f); } -// Returns the MiniTableEnum for this enum field. If the field is unlinked, -// returns NULL. +// Returns the MiniTableEnum for a message field, NULL if the field is unlinked. UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( - const upb_MiniTable* mini_table, const upb_MiniTableField* field) { - UPB_ASSERT(upb_MiniTableField_CType(field) == kUpb_CType_Enum); - return mini_table->subs[field->UPB_PRIVATE(submsg_index)].subenum; + const upb_MiniTable* m, const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTable_GetSubEnumTable)(m, f); +} + +// Returns the MiniTableField for the key of a map. +UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_MapKey( + const upb_MiniTable* m) { + return UPB_PRIVATE(_upb_MiniTable_MapKey)(m); +} + +// Returns the MiniTableField for the value of a map. +UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_MapValue( + const upb_MiniTable* m) { + return UPB_PRIVATE(_upb_MiniTable_MapValue)(m); } // Returns true if this MiniTable field is linked to a MiniTable for the // sub-message. UPB_API_INLINE bool upb_MiniTable_MessageFieldIsLinked( - const upb_MiniTable* mini_table, const upb_MiniTableField* field) { - return upb_MiniTable_GetSubMessageTable(mini_table, field) != NULL; + const upb_MiniTable* m, const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTable_MessageFieldIsLinked)(m, f); } // If this field is in a oneof, returns the first field in the oneof. @@ -1317,13 +1628,7 @@ extern "C" { #endif // Creates a new message with the given mini_table on the given arena. -UPB_API upb_Message* upb_Message_New(const upb_MiniTable* mini_table, - upb_Arena* arena); - -// Adds unknown data (serialized protobuf data) to the given message. -// The data is copied into the message instance. -void upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len, - upb_Arena* arena); +UPB_API upb_Message* upb_Message_New(const upb_MiniTable* m, upb_Arena* arena); // Returns a reference to the message's unknown data. const char* upb_Message_GetUnknown(const upb_Message* msg, size_t* len); @@ -1344,26 +1649,90 @@ size_t upb_Message_ExtensionCount(const upb_Message* msg); #ifndef UPB_MINI_TABLE_EXTENSION_H_ #define UPB_MINI_TABLE_EXTENSION_H_ +#include + #ifndef UPB_MINI_TABLE_INTERNAL_EXTENSION_H_ #define UPB_MINI_TABLE_INTERNAL_EXTENSION_H_ +#include + // Must be last. struct upb_MiniTableExtension { // Do not move this field. We need to be able to alias pointers. - struct upb_MiniTableField field; + struct upb_MiniTableField UPB_PRIVATE(field); - const struct upb_MiniTable* extendee; - union upb_MiniTableSub sub; // NULL unless submessage or proto2 enum + const struct upb_MiniTable* UPB_PRIVATE(extendee); + union upb_MiniTableSub UPB_PRIVATE(sub); // NULL unless submsg or proto2 enum }; +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE const struct upb_MiniTableField* UPB_PRIVATE( + _upb_MiniTableExtension_AsField)(const struct upb_MiniTableExtension* e) { + return (const struct upb_MiniTableField*)&e->UPB_PRIVATE(field); +} + +UPB_INLINE uint32_t UPB_PRIVATE(_upb_MiniTableExtension_Number)( + const struct upb_MiniTableExtension* e) { + return e->UPB_PRIVATE(field).UPB_ONLYBITS(number); +} + +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE( + _upb_MiniTableExtension_GetSubMessage)( + const struct upb_MiniTableExtension* e) { + return e->UPB_PRIVATE(sub).UPB_PRIVATE(submsg); +} + +UPB_INLINE void UPB_PRIVATE(_upb_MiniTableExtension_SetSubMessage)( + struct upb_MiniTableExtension* e, const struct upb_MiniTable* m) { + e->UPB_PRIVATE(sub).UPB_PRIVATE(submsg) = m; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif /* UPB_MINI_TABLE_INTERNAL_EXTENSION_H_ */ +// Must be last. + typedef struct upb_MiniTableExtension upb_MiniTableExtension; +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE const struct upb_MiniTableField* upb_MiniTableExtension_AsField( + const upb_MiniTableExtension* e) { + return UPB_PRIVATE(_upb_MiniTableExtension_AsField)(e); +} + +UPB_API_INLINE uint32_t +upb_MiniTableExtension_Number(const upb_MiniTableExtension* e) { + return UPB_PRIVATE(_upb_MiniTableExtension_Number)(e); +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableExtension_GetSubMessage( + const upb_MiniTableExtension* e) { + return UPB_PRIVATE(_upb_MiniTableExtension_GetSubMessage)(e); +} + +UPB_API_INLINE void upb_MiniTableExtension_SetSubMessage( + upb_MiniTableExtension* e, const struct upb_MiniTable* m) { + return UPB_PRIVATE(_upb_MiniTableExtension_SetSubMessage)(e, m); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + #endif /* UPB_MINI_TABLE_EXTENSION_H_ */ // Must be last. @@ -1991,80 +2360,6 @@ typedef struct { #endif // UPB_MINI_TABLE_INTERNAL_TYPES_H_ -#ifndef UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ -#define UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ - - -// Must be last. - -#ifdef __cplusplus -extern "C" { -#endif - -/* Extension registry: a dynamic data structure that stores a map of: - * (upb_MiniTable, number) -> extension info - * - * upb_decode() uses upb_ExtensionRegistry to look up extensions while parsing - * binary format. - * - * upb_ExtensionRegistry is part of the mini-table (msglayout) family of - * objects. Like all mini-table objects, it is suitable for reflection-less - * builds that do not want to expose names into the binary. - * - * Unlike most mini-table types, upb_ExtensionRegistry requires dynamic memory - * allocation and dynamic initialization: - * * If reflection is being used, then upb_DefPool will construct an appropriate - * upb_ExtensionRegistry automatically. - * * For a mini-table only build, the user must manually construct the - * upb_ExtensionRegistry and populate it with all of the extensions the user - * cares about. - * * A third alternative is to manually unpack relevant extensions after the - * main parse is complete, similar to how Any works. This is perhaps the - * nicest solution from the perspective of reducing dependencies, avoiding - * dynamic memory allocation, and avoiding the need to parse uninteresting - * extensions. The downsides are: - * (1) parse errors are not caught during the main parse - * (2) the CPU hit of parsing comes during access, which could cause an - * undesirable stutter in application performance. - * - * Users cannot directly get or put into this map. Users can only add the - * extensions from a generated module and pass the extension registry to the - * binary decoder. - * - * A upb_DefPool provides a upb_ExtensionRegistry, so any users who use - * reflection do not need to populate a upb_ExtensionRegistry directly. - */ - -typedef struct upb_ExtensionRegistry upb_ExtensionRegistry; - -// Creates a upb_ExtensionRegistry in the given arena. -// The arena must outlive any use of the extreg. -UPB_API upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena); - -UPB_API bool upb_ExtensionRegistry_Add(upb_ExtensionRegistry* r, - const upb_MiniTableExtension* e); - -// Adds the given extension info for the array |e| of size |count| into the -// registry. If there are any errors, the entire array is backed out. -// The extensions must outlive the registry. -// Possible errors include OOM or an extension number that already exists. -// TODO: There is currently no way to know the exact reason for failure. -bool upb_ExtensionRegistry_AddArray(upb_ExtensionRegistry* r, - const upb_MiniTableExtension** e, - size_t count); - -// Looks up the extension (if any) defined for message type |t| and field -// number |num|. Returns the extension if found, otherwise NULL. -UPB_API const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup( - const upb_ExtensionRegistry* r, const upb_MiniTable* t, uint32_t num); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ */ - // Must be last. #ifdef __cplusplus @@ -2104,11 +2399,8 @@ struct upb_Message_InternalData { * char data[size - sizeof(upb_Message_InternalData)]; */ }; -/* Maps upb_CType -> memory size. */ -extern char _upb_CTypeo_size[12]; - -UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* t) { - return t->size + sizeof(upb_Message_Internal); +UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* m) { + return m->UPB_PRIVATE(size) + sizeof(upb_Message_Internal); } // Inline version upb_Message_New(), for internal use. @@ -2133,8 +2425,11 @@ void _upb_Message_DiscardUnknown_shallow(upb_Message* msg); // Adds unknown data (serialized protobuf data) to the given message. // The data is copied into the message instance. -bool _upb_Message_AddUnknown(upb_Message* msg, const char* data, size_t len, - upb_Arena* arena); +bool UPB_PRIVATE(_upb_Message_AddUnknown)(upb_Message* msg, const char* data, + size_t len, upb_Arena* arena); + +bool UPB_PRIVATE(_upb_Message_Realloc)(upb_Message* msg, size_t need, + upb_Arena* arena); #ifdef __cplusplus } /* extern "C" */ @@ -2171,60 +2466,48 @@ extern "C" { // Hasbit access /////////////////////////////////////////////////////////////// -UPB_INLINE size_t _upb_hasbit_ofs(size_t idx) { return idx / 8; } - -UPB_INLINE char _upb_hasbit_mask(size_t idx) { return 1 << (idx % 8); } - -UPB_INLINE bool _upb_hasbit(const upb_Message* msg, size_t idx) { - return (*UPB_PTR_AT(msg, _upb_hasbit_ofs(idx), const char) & - _upb_hasbit_mask(idx)) != 0; +UPB_INLINE bool UPB_PRIVATE(_upb_Message_GetHasbit)( + const upb_Message* msg, const upb_MiniTableField* f) { + const size_t offset = _upb_MiniTableField_HasbitOffset(f); + const char mask = _upb_MiniTableField_HasbitMask(f); + return (*UPB_PTR_AT(msg, offset, const char) & mask) != 0; } -UPB_INLINE void _upb_sethas(const upb_Message* msg, size_t idx) { - (*UPB_PTR_AT(msg, _upb_hasbit_ofs(idx), char)) |= _upb_hasbit_mask(idx); +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetHasbit)( + const upb_Message* msg, const upb_MiniTableField* f) { + const size_t offset = _upb_MiniTableField_HasbitOffset(f); + const char mask = _upb_MiniTableField_HasbitMask(f); + (*UPB_PTR_AT(msg, offset, char)) |= mask; } -UPB_INLINE void _upb_clearhas(const upb_Message* msg, size_t idx) { - (*UPB_PTR_AT(msg, _upb_hasbit_ofs(idx), char)) &= ~_upb_hasbit_mask(idx); -} - -UPB_INLINE size_t _upb_Message_Hasidx(const upb_MiniTableField* f) { - UPB_ASSERT(f->presence > 0); - return f->presence; -} - -UPB_INLINE bool _upb_hasbit_field(const upb_Message* msg, - const upb_MiniTableField* f) { - return _upb_hasbit(msg, _upb_Message_Hasidx(f)); -} - -UPB_INLINE void _upb_sethas_field(const upb_Message* msg, - const upb_MiniTableField* f) { - _upb_sethas(msg, _upb_Message_Hasidx(f)); +UPB_INLINE void UPB_PRIVATE(_upb_Message_ClearHasbit)( + const upb_Message* msg, const upb_MiniTableField* f) { + const size_t offset = _upb_MiniTableField_HasbitOffset(f); + const char mask = _upb_MiniTableField_HasbitMask(f); + (*UPB_PTR_AT(msg, offset, char)) &= ~mask; } // Oneof case access /////////////////////////////////////////////////////////// -UPB_INLINE size_t _upb_oneofcase_ofs(const upb_MiniTableField* f) { - UPB_ASSERT(f->presence < 0); - return ~(ptrdiff_t)f->presence; +UPB_INLINE uint32_t* UPB_PRIVATE(_upb_Message_OneofCasePtr)( + upb_Message* msg, const upb_MiniTableField* f) { + return UPB_PTR_AT(msg, _upb_MiniTableField_OneofOffset(f), uint32_t); } -UPB_INLINE uint32_t* _upb_oneofcase_field(upb_Message* msg, - const upb_MiniTableField* f) { - return UPB_PTR_AT(msg, _upb_oneofcase_ofs(f), uint32_t); +UPB_INLINE uint32_t UPB_PRIVATE(_upb_Message_GetOneofCase)( + const upb_Message* msg, const upb_MiniTableField* f) { + return *UPB_PRIVATE(_upb_Message_OneofCasePtr)((upb_Message*)msg, f); } -UPB_INLINE uint32_t _upb_getoneofcase_field(const upb_Message* msg, - const upb_MiniTableField* f) { - return *_upb_oneofcase_field((upb_Message*)msg, f); +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetOneofCase)( + upb_Message* msg, const upb_MiniTableField* f) { + *UPB_PRIVATE(_upb_Message_OneofCasePtr)(msg, f) = + upb_MiniTableField_Number(f); } -// LINT.ThenChange(GoogleInternalName2) +// TODO: implement _upb_Message_ClearOneofCase() -UPB_INLINE bool _upb_MiniTableField_InOneOf(const upb_MiniTableField* field) { - return field->presence < 0; -} +// LINT.ThenChange(GoogleInternalName2) UPB_INLINE void* _upb_MiniTableField_GetPtr(upb_Message* msg, const upb_MiniTableField* field) { @@ -2236,36 +2519,42 @@ UPB_INLINE const void* _upb_MiniTableField_GetConstPtr( return (char*)msg + field->offset; } -UPB_INLINE void _upb_Message_SetPresence(upb_Message* msg, - const upb_MiniTableField* field) { +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetPresence)( + upb_Message* msg, const upb_MiniTableField* field) { if (field->presence > 0) { - _upb_sethas_field(msg, field); - } else if (_upb_MiniTableField_InOneOf(field)) { - *_upb_oneofcase_field(msg, field) = field->number; + UPB_PRIVATE(_upb_Message_SetHasbit)(msg, field); + } else if (upb_MiniTableField_IsInOneof(field)) { + UPB_PRIVATE(_upb_Message_SetOneofCase)(msg, field); } } -UPB_INLINE bool _upb_MiniTable_ValueIsNonZero(const void* default_val, - const upb_MiniTableField* field) { - char zero[16] = {0}; - switch (_upb_MiniTableField_GetRep(field)) { +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_DataEquals)( + const upb_MiniTableField* field, const void* a, const void* b) { + switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(field)) { case kUpb_FieldRep_1Byte: - return memcmp(&zero, default_val, 1) != 0; + return memcmp(a, b, 1) == 0; case kUpb_FieldRep_4Byte: - return memcmp(&zero, default_val, 4) != 0; + return memcmp(a, b, 4) == 0; case kUpb_FieldRep_8Byte: - return memcmp(&zero, default_val, 8) != 0; + return memcmp(a, b, 8) == 0; case kUpb_FieldRep_StringView: { - const upb_StringView* sv = (const upb_StringView*)default_val; - return sv->size != 0; + const upb_StringView sa = *(const upb_StringView*)a; + const upb_StringView sb = *(const upb_StringView*)b; + return upb_StringView_IsEqual(sa, sb); } } UPB_UNREACHABLE(); } -UPB_INLINE void _upb_MiniTable_CopyFieldData(void* to, const void* from, - const upb_MiniTableField* field) { - switch (_upb_MiniTableField_GetRep(field)) { +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_DataIsZero)( + const upb_MiniTableField* field, const void* val) { + const char zero[16] = {0}; + return UPB_PRIVATE(_upb_MiniTableField_DataEquals)(field, val, zero); +} + +UPB_INLINE void UPB_PRIVATE(_upb_MiniTableField_DataCopy)( + const upb_MiniTableField* field, void* to, const void* from) { + switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(field)) { case kUpb_FieldRep_1Byte: memcpy(to, from, 1); return; @@ -2283,32 +2572,6 @@ UPB_INLINE void _upb_MiniTable_CopyFieldData(void* to, const void* from, UPB_UNREACHABLE(); } -UPB_INLINE size_t -_upb_MiniTable_ElementSizeLg2(const upb_MiniTableField* field) { - const unsigned char table[] = { - 0, - 3, // kUpb_FieldType_Double = 1, - 2, // kUpb_FieldType_Float = 2, - 3, // kUpb_FieldType_Int64 = 3, - 3, // kUpb_FieldType_UInt64 = 4, - 2, // kUpb_FieldType_Int32 = 5, - 3, // kUpb_FieldType_Fixed64 = 6, - 2, // kUpb_FieldType_Fixed32 = 7, - 0, // kUpb_FieldType_Bool = 8, - UPB_SIZE(3, 4), // kUpb_FieldType_String = 9, - UPB_SIZE(2, 3), // kUpb_FieldType_Group = 10, - UPB_SIZE(2, 3), // kUpb_FieldType_Message = 11, - UPB_SIZE(3, 4), // kUpb_FieldType_Bytes = 12, - 2, // kUpb_FieldType_UInt32 = 13, - 2, // kUpb_FieldType_Enum = 14, - 2, // kUpb_FieldType_SFixed32 = 15, - 3, // kUpb_FieldType_SFixed64 = 16, - 2, // kUpb_FieldType_SInt32 = 17, - 3, // kUpb_FieldType_SInt64 = 18, - }; - return table[field->UPB_PRIVATE(descriptortype)]; -} - // Here we define universal getter/setter functions for message fields. // These look very branchy and inefficient, but as long as the MiniTableField // values are known at compile time, all the branches are optimized away and @@ -2327,9 +2590,10 @@ _upb_MiniTable_ElementSizeLg2(const upb_MiniTableField* field) { // const upb_MiniTableField* field, // bool value, upb_Arena* a) { // UPB_ASSUME(field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bool); -// UPB_ASSUME(!upb_IsRepeatedOrMap(field)); -// UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_1Byte); -// _upb_Message_SetField(msg, field, &value, a); +// UPB_ASSUME(upb_MiniTableField_IsScalar(field)); +// UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == +// kUpb_FieldRep_1Byte); +// upb_Message_SetField(msg, field, &value, a); // } // // As a result, we can use these universal getters/setters for *all* message @@ -2343,7 +2607,7 @@ _upb_MiniTable_ElementSizeLg2(const upb_MiniTableField* field) { UPB_INLINE bool _upb_Message_HasExtensionField( const upb_Message* msg, const upb_MiniTableExtension* ext) { - UPB_ASSERT(upb_MiniTableField_HasPresence(&ext->field)); + UPB_ASSERT(upb_MiniTableField_HasPresence(&ext->UPB_PRIVATE(field))); return _upb_Message_Getext(msg, ext) != NULL; } @@ -2351,10 +2615,11 @@ UPB_INLINE bool _upb_Message_HasNonExtensionField( const upb_Message* msg, const upb_MiniTableField* field) { UPB_ASSERT(upb_MiniTableField_HasPresence(field)); UPB_ASSUME(!upb_MiniTableField_IsExtension(field)); - if (_upb_MiniTableField_InOneOf(field)) { - return _upb_getoneofcase_field(msg, field) == field->number; + if (upb_MiniTableField_IsInOneof(field)) { + return UPB_PRIVATE(_upb_Message_GetOneofCase)(msg, field) == + upb_MiniTableField_Number(field); } else { - return _upb_hasbit_field(msg, field); + return UPB_PRIVATE(_upb_Message_GetHasbit)(msg, field); } } @@ -2362,45 +2627,63 @@ static UPB_FORCEINLINE void _upb_Message_GetNonExtensionField( const upb_Message* msg, const upb_MiniTableField* field, const void* default_val, void* val) { UPB_ASSUME(!upb_MiniTableField_IsExtension(field)); - if ((_upb_MiniTableField_InOneOf(field) || - _upb_MiniTable_ValueIsNonZero(default_val, field)) && + if ((upb_MiniTableField_IsInOneof(field) || + !UPB_PRIVATE(_upb_MiniTableField_DataIsZero)(field, default_val)) && !_upb_Message_HasNonExtensionField(msg, field)) { - _upb_MiniTable_CopyFieldData(val, default_val, field); + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(field, val, default_val); return; } - _upb_MiniTable_CopyFieldData(val, _upb_MiniTableField_GetConstPtr(msg, field), - field); + UPB_PRIVATE(_upb_MiniTableField_DataCopy) + (field, val, _upb_MiniTableField_GetConstPtr(msg, field)); } UPB_INLINE void _upb_Message_GetExtensionField( const upb_Message* msg, const upb_MiniTableExtension* mt_ext, const void* default_val, void* val) { - UPB_ASSUME(upb_MiniTableField_IsExtension(&mt_ext->field)); const upb_Message_Extension* ext = _upb_Message_Getext(msg, mt_ext); + const upb_MiniTableField* f = &mt_ext->UPB_PRIVATE(field); + UPB_ASSUME(upb_MiniTableField_IsExtension(f)); + if (ext) { - _upb_MiniTable_CopyFieldData(val, &ext->data, &mt_ext->field); + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f, val, &ext->data); } else { - _upb_MiniTable_CopyFieldData(val, default_val, &mt_ext->field); + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f, val, default_val); } } -UPB_INLINE void _upb_Message_GetField(const upb_Message* msg, - const upb_MiniTableField* field, - const void* default_val, void* val) { +// Gets a mutable Array, Map or Message field. +// NOTE: For repeated/map fields, the resulting upb_Array*/upb_Map* can +// be NULL if a upb_Array/upb_Map has not been allocated yet. Array/map +// fields do not have presence, so this is semantically identical to a +// pointer to an empty array/map, and must be treated the same for all +// semantic purposes. +// +// For message fields, the pointer is guaranteed to be NULL iff the field +// is unset (as message fields do have presence). +UPB_INLINE upb_MutableMessageValue _upb_Message_GetMutableField( + const upb_Message* msg, const upb_MiniTableField* field) { + UPB_ASSUME(!upb_MiniTableField_IsScalar(field) || + upb_MiniTableField_IsSubMessage(field)); + + upb_MutableMessageValue default_val; + default_val.msg = NULL; + + upb_MutableMessageValue ret; if (upb_MiniTableField_IsExtension(field)) { _upb_Message_GetExtensionField(msg, (upb_MiniTableExtension*)field, - default_val, val); + &default_val, &ret); } else { - _upb_Message_GetNonExtensionField(msg, field, default_val, val); + _upb_Message_GetNonExtensionField(msg, field, &default_val, &ret); } + return ret; } UPB_INLINE void _upb_Message_SetNonExtensionField( upb_Message* msg, const upb_MiniTableField* field, const void* val) { UPB_ASSUME(!upb_MiniTableField_IsExtension(field)); - _upb_Message_SetPresence(msg, field); - _upb_MiniTable_CopyFieldData(_upb_MiniTableField_GetPtr(msg, field), val, - field); + UPB_PRIVATE(_upb_Message_SetPresence)(msg, field); + UPB_PRIVATE(_upb_MiniTableField_DataCopy) + (field, _upb_MiniTableField_GetPtr(msg, field), val); } UPB_INLINE bool _upb_Message_SetExtensionField( @@ -2410,22 +2693,11 @@ UPB_INLINE bool _upb_Message_SetExtensionField( upb_Message_Extension* ext = _upb_Message_GetOrCreateExtension(msg, mt_ext, a); if (!ext) return false; - _upb_MiniTable_CopyFieldData(&ext->data, val, &mt_ext->field); + UPB_PRIVATE(_upb_MiniTableField_DataCopy) + (&mt_ext->UPB_PRIVATE(field), &ext->data, val); return true; } -UPB_INLINE bool _upb_Message_SetField(upb_Message* msg, - const upb_MiniTableField* field, - const void* val, upb_Arena* a) { - if (upb_MiniTableField_IsExtension(field)) { - const upb_MiniTableExtension* ext = (const upb_MiniTableExtension*)field; - return _upb_Message_SetExtensionField(msg, ext, val, a); - } else { - _upb_Message_SetNonExtensionField(msg, field, val); - return true; - } -} - UPB_INLINE void _upb_Message_ClearExtensionField( upb_Message* msg, const upb_MiniTableExtension* ext_l) { upb_Message_Internal* in = upb_Message_Getinternal(msg); @@ -2443,21 +2715,21 @@ UPB_INLINE void _upb_Message_ClearExtensionField( UPB_INLINE void _upb_Message_ClearNonExtensionField( upb_Message* msg, const upb_MiniTableField* field) { if (field->presence > 0) { - _upb_clearhas(msg, _upb_Message_Hasidx(field)); - } else if (_upb_MiniTableField_InOneOf(field)) { - uint32_t* oneof_case = _upb_oneofcase_field(msg, field); - if (*oneof_case != field->number) return; - *oneof_case = 0; + UPB_PRIVATE(_upb_Message_ClearHasbit)(msg, field); + } else if (upb_MiniTableField_IsInOneof(field)) { + uint32_t* ptr = UPB_PRIVATE(_upb_Message_OneofCasePtr)(msg, field); + if (*ptr != upb_MiniTableField_Number(field)) return; + *ptr = 0; } const char zeros[16] = {0}; - _upb_MiniTable_CopyFieldData(_upb_MiniTableField_GetPtr(msg, field), zeros, - field); + UPB_PRIVATE(_upb_MiniTableField_DataCopy) + (field, _upb_MiniTableField_GetPtr(msg, field), zeros); } UPB_INLINE void _upb_Message_AssertMapIsUntagged( const upb_Message* msg, const upb_MiniTableField* field) { UPB_UNUSED(msg); - _upb_MiniTableField_CheckIsMap(field); + UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(field); #ifndef NDEBUG upb_TaggedMessagePtr default_val = 0; upb_TaggedMessagePtr tagged; @@ -2469,7 +2741,7 @@ UPB_INLINE void _upb_Message_AssertMapIsUntagged( UPB_INLINE upb_Map* _upb_Message_GetOrCreateMutableMap( upb_Message* msg, const upb_MiniTableField* field, size_t key_size, size_t val_size, upb_Arena* arena) { - _upb_MiniTableField_CheckIsMap(field); + UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(field); _upb_Message_AssertMapIsUntagged(msg, field); upb_Map* map = NULL; upb_Map* default_map_value = NULL; @@ -2477,7 +2749,7 @@ UPB_INLINE upb_Map* _upb_Message_GetOrCreateMutableMap( if (!map) { map = _upb_Map_New(arena, key_size, val_size); // Check again due to: https://godbolt.org/z/7WfaoKG1r - _upb_MiniTableField_CheckIsMap(field); + UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(field); _upb_Message_SetNonExtensionField(msg, field, &map); } return map; @@ -2502,6 +2774,10 @@ UPB_INLINE upb_Map* _upb_Message_GetOrCreateMutableMap( // Must be last. +#define _UPB_ARRAY_MASK_IMM 0x4 // Frozen/immutable bit. +#define _UPB_ARRAY_MASK_LG2 0x3 // Encoded elem size. +#define _UPB_ARRAY_MASK_ALL (_UPB_ARRAY_MASK_IMM | _UPB_ARRAY_MASK_LG2) + #ifdef __cplusplus extern "C" { #endif @@ -2509,97 +2785,148 @@ extern "C" { // LINT.IfChange(struct_definition) // Our internal representation for repeated fields. struct upb_Array { - uintptr_t data; /* Tagged ptr: low 3 bits of ptr are lg2(elem size). */ - size_t size; /* The number of elements in the array. */ - size_t capacity; /* Allocated storage. Measured in elements. */ + // This is a tagged pointer. Bits #0 and #1 encode the elem size as follows: + // 0 maps to elem size 1 + // 1 maps to elem size 4 + // 2 maps to elem size 8 + // 3 maps to elem size 16 + // + // Bit #2 contains the frozen/immutable flag (currently unimplemented). + uintptr_t data; + + size_t size; // The number of elements in the array. + size_t UPB_PRIVATE(capacity); // Allocated storage. Measured in elements. }; -// LINT.ThenChange(GoogleInternalName1) - -UPB_INLINE size_t _upb_Array_ElementSizeLg2(const upb_Array* arr) { - size_t ret = arr->data & 7; - UPB_ASSERT(ret <= 4); - return ret; -} -UPB_INLINE const void* _upb_array_constptr(const upb_Array* arr) { - _upb_Array_ElementSizeLg2(arr); // Check assertion. - return (void*)(arr->data & ~(uintptr_t)7); +UPB_INLINE void UPB_PRIVATE(_upb_Array_SetTaggedPtr)(upb_Array* array, + void* data, size_t lg2) { + UPB_ASSERT(lg2 != 1); + UPB_ASSERT(lg2 <= 4); + const size_t bits = lg2 - (lg2 != 0); + array->data = (uintptr_t)data | bits; } -UPB_INLINE uintptr_t _upb_array_tagptr(void* ptr, int elem_size_lg2) { - UPB_ASSERT(elem_size_lg2 <= 4); - return (uintptr_t)ptr | elem_size_lg2; -} - -UPB_INLINE void* _upb_array_ptr(upb_Array* arr) { - return (void*)_upb_array_constptr(arr); +UPB_INLINE size_t UPB_PRIVATE(_upb_Array_ElemSizeLg2)(const upb_Array* array) { + const size_t bits = array->data & _UPB_ARRAY_MASK_LG2; + const size_t lg2 = bits + (bits != 0); + return lg2; } -UPB_INLINE uintptr_t _upb_tag_arrptr(void* ptr, int elem_size_lg2) { - UPB_ASSERT(elem_size_lg2 <= 4); - UPB_ASSERT(((uintptr_t)ptr & 7) == 0); - return (uintptr_t)ptr | (unsigned)elem_size_lg2; +UPB_INLINE const void* _upb_array_constptr(const upb_Array* array) { + UPB_PRIVATE(_upb_Array_ElemSizeLg2)(array); // Check assertions. + return (void*)(array->data & ~(uintptr_t)_UPB_ARRAY_MASK_ALL); } -extern const char _upb_Array_CTypeSizeLg2Table[]; - -UPB_INLINE size_t _upb_Array_CTypeSizeLg2(upb_CType ctype) { - return _upb_Array_CTypeSizeLg2Table[ctype]; +UPB_INLINE void* _upb_array_ptr(upb_Array* array) { + return (void*)_upb_array_constptr(array); } -UPB_INLINE upb_Array* _upb_Array_New(upb_Arena* a, size_t init_capacity, - int elem_size_lg2) { +UPB_INLINE upb_Array* UPB_PRIVATE(_upb_Array_New)(upb_Arena* arena, + size_t init_capacity, + int elem_size_lg2) { + UPB_ASSERT(elem_size_lg2 != 1); UPB_ASSERT(elem_size_lg2 <= 4); - const size_t arr_size = UPB_ALIGN_UP(sizeof(upb_Array), UPB_MALLOC_ALIGN); - const size_t bytes = arr_size + (init_capacity << elem_size_lg2); - upb_Array* arr = (upb_Array*)upb_Arena_Malloc(a, bytes); - if (!arr) return NULL; - arr->data = _upb_tag_arrptr(UPB_PTR_AT(arr, arr_size, void), elem_size_lg2); - arr->size = 0; - arr->capacity = init_capacity; - return arr; + const size_t array_size = UPB_ALIGN_UP(sizeof(upb_Array), UPB_MALLOC_ALIGN); + const size_t bytes = array_size + (init_capacity << elem_size_lg2); + upb_Array* array = (upb_Array*)upb_Arena_Malloc(arena, bytes); + if (!array) return NULL; + UPB_PRIVATE(_upb_Array_SetTaggedPtr) + (array, UPB_PTR_AT(array, array_size, void), elem_size_lg2); + array->size = 0; + array->UPB_PRIVATE(capacity) = init_capacity; + return array; } // Resizes the capacity of the array to be at least min_size. -bool _upb_array_realloc(upb_Array* arr, size_t min_size, upb_Arena* arena); +bool UPB_PRIVATE(_upb_Array_Realloc)(upb_Array* array, size_t min_size, + upb_Arena* arena); -UPB_INLINE bool _upb_array_reserve(upb_Array* arr, size_t size, - upb_Arena* arena) { - if (arr->capacity < size) return _upb_array_realloc(arr, size, arena); +UPB_INLINE bool UPB_PRIVATE(_upb_Array_Reserve)(upb_Array* array, size_t size, + upb_Arena* arena) { + if (array->UPB_PRIVATE(capacity) < size) + return UPB_PRIVATE(_upb_Array_Realloc)(array, size, arena); return true; } // Resize without initializing new elements. -UPB_INLINE bool _upb_Array_ResizeUninitialized(upb_Array* arr, size_t size, +UPB_INLINE bool _upb_Array_ResizeUninitialized(upb_Array* array, size_t size, upb_Arena* arena) { - UPB_ASSERT(size <= arr->size || arena); // Allow NULL arena when shrinking. - if (!_upb_array_reserve(arr, size, arena)) return false; - arr->size = size; + UPB_ASSERT(size <= array->size || arena); // Allow NULL arena when shrinking. + if (!UPB_PRIVATE(_upb_Array_Reserve)(array, size, arena)) return false; + array->size = size; return true; } // This function is intended for situations where elem_size is compile-time // constant or a known expression of the form (1 << lg2), so that the expression // i*elem_size does not result in an actual multiplication. -UPB_INLINE void _upb_Array_Set(upb_Array* arr, size_t i, const void* data, - size_t elem_size) { - UPB_ASSERT(i < arr->size); - UPB_ASSERT(elem_size == 1U << _upb_Array_ElementSizeLg2(arr)); - char* arr_data = (char*)_upb_array_ptr(arr); +UPB_INLINE void UPB_PRIVATE(_upb_Array_Set)(upb_Array* array, size_t i, + const void* data, + size_t elem_size) { + UPB_ASSERT(i < array->size); + UPB_ASSERT(elem_size == 1U << UPB_PRIVATE(_upb_Array_ElemSizeLg2)(array)); + char* arr_data = (char*)_upb_array_ptr(array); memcpy(arr_data + (i * elem_size), data, elem_size); } -UPB_INLINE void _upb_array_detach(const void* msg, size_t ofs) { - *UPB_PTR_AT(msg, ofs, upb_Array*) = NULL; -} +// LINT.ThenChange( +// GoogleInternalName1, +//) #ifdef __cplusplus } /* extern "C" */ #endif +#undef _UPB_ARRAY_MASK_IMM +#undef _UPB_ARRAY_MASK_LG2 +#undef _UPB_ARRAY_MASK_ALL + #endif /* UPB_MESSAGE_INTERNAL_ARRAY_H_ */ +#ifndef UPB_MINI_TABLE_SUB_H_ +#define UPB_MINI_TABLE_SUB_H_ + + +// Must be last. + +typedef union upb_MiniTableSub upb_MiniTableSub; + +#ifdef __cplusplus +extern "C" { +#endif + +// Constructors + +UPB_API_INLINE upb_MiniTableSub +upb_MiniTableSub_FromEnum(const struct upb_MiniTableEnum* subenum) { + return UPB_PRIVATE(_upb_MiniTableSub_FromEnum)(subenum); +} + +UPB_API_INLINE upb_MiniTableSub +upb_MiniTableSub_FromMessage(const struct upb_MiniTable* submsg) { + return UPB_PRIVATE(_upb_MiniTableSub_FromMessage)(submsg); +} + +// Getters + +UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTableSub_Enum( + upb_MiniTableSub sub) { + return UPB_PRIVATE(_upb_MiniTableSub_Enum)(sub); +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableSub_Message( + upb_MiniTableSub sub) { + return UPB_PRIVATE(_upb_MiniTableSub_Message)(sub); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_SUB_H_ */ + // Must be last. #ifdef __cplusplus @@ -2635,28 +2962,62 @@ UPB_API_INLINE bool upb_Message_HasField(const upb_Message* msg, UPB_API_INLINE uint32_t upb_Message_WhichOneofFieldNumber( const upb_Message* message, const upb_MiniTableField* oneof_field) { - UPB_ASSUME(_upb_MiniTableField_InOneOf(oneof_field)); - return _upb_getoneofcase_field(message, oneof_field); + UPB_ASSUME(upb_MiniTableField_IsInOneof(oneof_field)); + return UPB_PRIVATE(_upb_Message_GetOneofCase)(message, oneof_field); +} + +// NOTE: The default_val is only used for fields that support presence. +// For repeated/map fields, the resulting upb_Array*/upb_Map* can be NULL if a +// upb_Array/upb_Map has not been allocated yet. Array/map fields do not have +// presence, so this is semantically identical to a pointer to an empty +// array/map, and must be treated the same for all semantic purposes. +UPB_INLINE upb_MessageValue +upb_Message_GetField(const upb_Message* msg, const upb_MiniTableField* field, + upb_MessageValue default_val) { + upb_MessageValue ret; + if (upb_MiniTableField_IsExtension(field)) { + _upb_Message_GetExtensionField(msg, (upb_MiniTableExtension*)field, + &default_val, &ret); + } else { + _upb_Message_GetNonExtensionField(msg, field, &default_val, &ret); + } + return ret; +} + +UPB_INLINE bool upb_Message_SetField(upb_Message* msg, + const upb_MiniTableField* field, + upb_MessageValue val, upb_Arena* a) { + if (upb_MiniTableField_IsExtension(field)) { + const upb_MiniTableExtension* ext = (const upb_MiniTableExtension*)field; + return _upb_Message_SetExtensionField(msg, ext, &val, a); + } else { + _upb_Message_SetNonExtensionField(msg, field, &val); + return true; + } } UPB_API_INLINE bool upb_Message_GetBool(const upb_Message* msg, const upb_MiniTableField* field, bool default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Bool); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_1Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - bool ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_1Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue def; + def.bool_val = default_val; + return upb_Message_GetField(msg, field, def).bool_val; } UPB_API_INLINE bool upb_Message_SetBool(upb_Message* msg, const upb_MiniTableField* field, bool value, upb_Arena* a) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Bool); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_1Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_1Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue val; + val.bool_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE int32_t upb_Message_GetInt32(const upb_Message* msg, @@ -2664,11 +3025,13 @@ UPB_API_INLINE int32_t upb_Message_GetInt32(const upb_Message* msg, int32_t default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Int32 || upb_MiniTableField_CType(field) == kUpb_CType_Enum); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - int32_t ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_4Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + + upb_MessageValue def; + def.int32_val = default_val; + return upb_Message_GetField(msg, field, def).int32_val; } UPB_API_INLINE bool upb_Message_SetInt32(upb_Message* msg, @@ -2676,37 +3039,46 @@ UPB_API_INLINE bool upb_Message_SetInt32(upb_Message* msg, int32_t value, upb_Arena* a) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Int32 || upb_MiniTableField_CType(field) == kUpb_CType_Enum); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_4Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue val; + val.int32_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE uint32_t upb_Message_GetUInt32(const upb_Message* msg, const upb_MiniTableField* field, uint32_t default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt32); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - uint32_t ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_4Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + + upb_MessageValue def; + def.uint32_val = default_val; + return upb_Message_GetField(msg, field, def).uint32_val; } UPB_API_INLINE bool upb_Message_SetUInt32(upb_Message* msg, const upb_MiniTableField* field, uint32_t value, upb_Arena* a) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt32); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_4Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue val; + val.uint32_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE void upb_Message_SetClosedEnum( upb_Message* msg, const upb_MiniTable* msg_mini_table, const upb_MiniTableField* field, int32_t value) { UPB_ASSERT(upb_MiniTableField_IsClosedEnum(field)); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_4Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); UPB_ASSERT(upb_MiniTableEnum_CheckValue( upb_MiniTable_GetSubEnumTable(msg_mini_table, field), value)); _upb_Message_SetNonExtensionField(msg, field, &value); @@ -2714,94 +3086,116 @@ UPB_API_INLINE void upb_Message_SetClosedEnum( UPB_API_INLINE int64_t upb_Message_GetInt64(const upb_Message* msg, const upb_MiniTableField* field, - uint64_t default_val) { + int64_t default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Int64); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - int64_t ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_8Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + + upb_MessageValue def; + def.int64_val = default_val; + return upb_Message_GetField(msg, field, def).int64_val; } UPB_API_INLINE bool upb_Message_SetInt64(upb_Message* msg, const upb_MiniTableField* field, int64_t value, upb_Arena* a) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Int64); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_8Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue val; + val.int64_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE uint64_t upb_Message_GetUInt64(const upb_Message* msg, const upb_MiniTableField* field, uint64_t default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt64); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - uint64_t ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_8Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + + upb_MessageValue def; + def.uint64_val = default_val; + return upb_Message_GetField(msg, field, def).uint64_val; } UPB_API_INLINE bool upb_Message_SetUInt64(upb_Message* msg, const upb_MiniTableField* field, uint64_t value, upb_Arena* a) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_UInt64); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_8Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue val; + val.uint64_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE float upb_Message_GetFloat(const upb_Message* msg, const upb_MiniTableField* field, float default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Float); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - float ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_4Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + + upb_MessageValue def; + def.float_val = default_val; + return upb_Message_GetField(msg, field, def).float_val; } UPB_API_INLINE bool upb_Message_SetFloat(upb_Message* msg, const upb_MiniTableField* field, float value, upb_Arena* a) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Float); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_4Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_4Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue val; + val.float_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE double upb_Message_GetDouble(const upb_Message* msg, const upb_MiniTableField* field, double default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Double); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - double ret; - _upb_Message_GetField(msg, field, &default_val, &ret); - return ret; + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_8Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + + upb_MessageValue def; + def.double_val = default_val; + return upb_Message_GetField(msg, field, def).double_val; } UPB_API_INLINE bool upb_Message_SetDouble(upb_Message* msg, const upb_MiniTableField* field, double value, upb_Arena* a) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Double); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_8Byte); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_8Byte); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue val; + val.double_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE upb_StringView upb_Message_GetString(const upb_Message* msg, const upb_MiniTableField* field, - upb_StringView def_val) { + upb_StringView default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_String || upb_MiniTableField_CType(field) == kUpb_CType_Bytes); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_StringView); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - upb_StringView ret; - _upb_Message_GetField(msg, field, &def_val, &ret); - return ret; + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_StringView); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + + upb_MessageValue def; + def.str_val = default_val; + return upb_Message_GetField(msg, field, def).str_val; } UPB_API_INLINE bool upb_Message_SetString(upb_Message* msg, @@ -2809,18 +3203,21 @@ UPB_API_INLINE bool upb_Message_SetString(upb_Message* msg, upb_StringView value, upb_Arena* a) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_String || upb_MiniTableField_CType(field) == kUpb_CType_Bytes); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == kUpb_FieldRep_StringView); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - return _upb_Message_SetField(msg, field, &value, a); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == + kUpb_FieldRep_StringView); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + upb_MessageValue val; + val.str_val = value; + return upb_Message_SetField(msg, field, val, a); } UPB_API_INLINE upb_TaggedMessagePtr upb_Message_GetTaggedMessagePtr( const upb_Message* msg, const upb_MiniTableField* field, upb_Message* default_val) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Message); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); upb_TaggedMessagePtr tagged; _upb_Message_GetNonExtensionField(msg, field, &default_val, &tagged); return tagged; @@ -2841,10 +3238,11 @@ UPB_API_INLINE void _upb_Message_SetTaggedMessagePtr( upb_Message* msg, const upb_MiniTable* mini_table, const upb_MiniTableField* field, upb_TaggedMessagePtr sub_message) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Message); - UPB_ASSUME(_upb_MiniTableField_GetRep(field) == + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); - UPB_ASSUME(!upb_IsRepeatedOrMap(field)); - UPB_ASSERT(mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg); + UPB_ASSUME(upb_MiniTableField_IsScalar(field)); + UPB_ASSERT(upb_MiniTableSub_Message( + mini_table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)])); _upb_Message_SetNonExtensionField(msg, field, &sub_message); } @@ -2863,19 +3261,19 @@ UPB_API_INLINE upb_Message* upb_Message_GetOrCreateMutableMessage( UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Message); upb_Message* sub_message = *UPB_PTR_AT(msg, field->offset, upb_Message*); if (!sub_message) { - const upb_MiniTable* sub_mini_table = - mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* sub_mini_table = upb_MiniTableSub_Message( + mini_table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]); UPB_ASSERT(sub_mini_table); sub_message = _upb_Message_New(sub_mini_table, arena); *UPB_PTR_AT(msg, field->offset, upb_Message*) = sub_message; - _upb_Message_SetPresence(msg, field); + UPB_PRIVATE(_upb_Message_SetPresence)(msg, field); } return sub_message; } UPB_API_INLINE const upb_Array* upb_Message_GetArray( const upb_Message* msg, const upb_MiniTableField* field) { - _upb_MiniTableField_CheckIsArray(field); + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(field); upb_Array* ret; const upb_Array* default_val = NULL; _upb_Message_GetNonExtensionField(msg, field, &default_val, &ret); @@ -2884,20 +3282,23 @@ UPB_API_INLINE const upb_Array* upb_Message_GetArray( UPB_API_INLINE upb_Array* upb_Message_GetMutableArray( upb_Message* msg, const upb_MiniTableField* field) { - _upb_MiniTableField_CheckIsArray(field); + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(field); return (upb_Array*)upb_Message_GetArray(msg, field); } UPB_API_INLINE upb_Array* upb_Message_GetOrCreateMutableArray( upb_Message* msg, const upb_MiniTableField* field, upb_Arena* arena) { UPB_ASSERT(arena); - _upb_MiniTableField_CheckIsArray(field); + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(field); upb_Array* array = upb_Message_GetMutableArray(msg, field); if (!array) { - array = _upb_Array_New(arena, 4, _upb_MiniTable_ElementSizeLg2(field)); + array = UPB_PRIVATE(_upb_Array_New)( + arena, 4, UPB_PRIVATE(_upb_MiniTableField_ElemSizeLg2)(field)); // Check again due to: https://godbolt.org/z/7WfaoKG1r - _upb_MiniTableField_CheckIsArray(field); - _upb_Message_SetField(msg, field, &array, arena); + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(field); + upb_MessageValue val; + val.array_val = array; + upb_Message_SetField(msg, field, val, arena); } return array; } @@ -2905,7 +3306,7 @@ UPB_API_INLINE upb_Array* upb_Message_GetOrCreateMutableArray( UPB_API_INLINE void* upb_Message_ResizeArrayUninitialized( upb_Message* msg, const upb_MiniTableField* field, size_t size, upb_Arena* arena) { - _upb_MiniTableField_CheckIsArray(field); + UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(field); upb_Array* arr = upb_Message_GetOrCreateMutableArray(msg, field, arena); if (!arr || !_upb_Array_ResizeUninitialized(arr, size, arena)) return NULL; return _upb_array_ptr(arr); @@ -2913,7 +3314,7 @@ UPB_API_INLINE void* upb_Message_ResizeArrayUninitialized( UPB_API_INLINE const upb_Map* upb_Message_GetMap( const upb_Message* msg, const upb_MiniTableField* field) { - _upb_MiniTableField_CheckIsMap(field); + UPB_PRIVATE(_upb_MiniTableField_CheckIsMap)(field); _upb_Message_AssertMapIsUntagged(msg, field); upb_Map* ret; const upb_Map* default_val = NULL; @@ -2931,9 +3332,9 @@ UPB_API_INLINE upb_Map* upb_Message_GetOrCreateMutableMap( const upb_MiniTableField* field, upb_Arena* arena) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Message); const upb_MiniTableField* map_entry_key_field = - &map_entry_mini_table->fields[0]; + &map_entry_mini_table->UPB_PRIVATE(fields)[0]; const upb_MiniTableField* map_entry_value_field = - &map_entry_mini_table->fields[1]; + &map_entry_mini_table->UPB_PRIVATE(fields)[1]; return _upb_Message_GetOrCreateMutableMap( msg, field, _upb_Map_CTypeSize(upb_MiniTableField_CType(map_entry_key_field)), @@ -3012,14 +3413,6 @@ UPB_INLINE void _upb_msg_map_set_value(void* msg, const void* val, #define UPB_MINI_TABLE_DECODE_H_ -#ifndef UPB_MINI_TABLE_SUB_H_ -#define UPB_MINI_TABLE_SUB_H_ - - -typedef union upb_MiniTableSub upb_MiniTableSub; - -#endif /* UPB_MINI_TABLE_INTERNAL_SUB_H_ */ - // Export the newer headers, for legacy users. New users should include the // more specific headers directly. // IWYU pragma: begin_exports @@ -3179,8 +3572,7 @@ UPB_API upb_MiniTableExtension* _upb_MiniTableExtension_Build( UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_Build( const char* data, size_t len, const upb_MiniTable* extendee, upb_Arena* arena, upb_Status* status) { - upb_MiniTableSub sub; - sub.submsg = NULL; + upb_MiniTableSub sub = upb_MiniTableSub_FromMessage(NULL); return _upb_MiniTableExtension_Build( data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status); } @@ -3188,8 +3580,7 @@ UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_Build( UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_BuildMessage( const char* data, size_t len, const upb_MiniTable* extendee, upb_MiniTable* submsg, upb_Arena* arena, upb_Status* status) { - upb_MiniTableSub sub; - sub.submsg = submsg; + upb_MiniTableSub sub = upb_MiniTableSub_FromMessage(submsg); return _upb_MiniTableExtension_Build( data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status); } @@ -3197,8 +3588,7 @@ UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_BuildMessage( UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_BuildEnum( const char* data, size_t len, const upb_MiniTable* extendee, upb_MiniTableEnum* subenum, upb_Arena* arena, upb_Status* status) { - upb_MiniTableSub sub; - sub.subenum = subenum; + upb_MiniTableSub sub = upb_MiniTableSub_FromEnum(subenum); return _upb_MiniTableExtension_Build( data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status); } @@ -3221,6 +3611,80 @@ upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len, #endif /* UPB_MINI_TABLE_DECODE_H_ */ +#ifndef UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ +#define UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +/* Extension registry: a dynamic data structure that stores a map of: + * (upb_MiniTable, number) -> extension info + * + * upb_decode() uses upb_ExtensionRegistry to look up extensions while parsing + * binary format. + * + * upb_ExtensionRegistry is part of the mini-table (msglayout) family of + * objects. Like all mini-table objects, it is suitable for reflection-less + * builds that do not want to expose names into the binary. + * + * Unlike most mini-table types, upb_ExtensionRegistry requires dynamic memory + * allocation and dynamic initialization: + * * If reflection is being used, then upb_DefPool will construct an appropriate + * upb_ExtensionRegistry automatically. + * * For a mini-table only build, the user must manually construct the + * upb_ExtensionRegistry and populate it with all of the extensions the user + * cares about. + * * A third alternative is to manually unpack relevant extensions after the + * main parse is complete, similar to how Any works. This is perhaps the + * nicest solution from the perspective of reducing dependencies, avoiding + * dynamic memory allocation, and avoiding the need to parse uninteresting + * extensions. The downsides are: + * (1) parse errors are not caught during the main parse + * (2) the CPU hit of parsing comes during access, which could cause an + * undesirable stutter in application performance. + * + * Users cannot directly get or put into this map. Users can only add the + * extensions from a generated module and pass the extension registry to the + * binary decoder. + * + * A upb_DefPool provides a upb_ExtensionRegistry, so any users who use + * reflection do not need to populate a upb_ExtensionRegistry directly. + */ + +typedef struct upb_ExtensionRegistry upb_ExtensionRegistry; + +// Creates a upb_ExtensionRegistry in the given arena. +// The arena must outlive any use of the extreg. +UPB_API upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena); + +UPB_API bool upb_ExtensionRegistry_Add(upb_ExtensionRegistry* r, + const upb_MiniTableExtension* e); + +// Adds the given extension info for the array |e| of size |count| into the +// registry. If there are any errors, the entire array is backed out. +// The extensions must outlive the registry. +// Possible errors include OOM or an extension number that already exists. +// TODO: There is currently no way to know the exact reason for failure. +bool upb_ExtensionRegistry_AddArray(upb_ExtensionRegistry* r, + const upb_MiniTableExtension** e, + size_t count); + +// Looks up the extension (if any) defined for message type |t| and field +// number |num|. Returns the extension if found, otherwise NULL. +UPB_API const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup( + const upb_ExtensionRegistry* r, const upb_MiniTable* t, uint32_t num); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_MINI_TABLE_EXTENSION_REGISTRY_H_ */ + #ifndef UPB_MINI_TABLE_FILE_H_ #define UPB_MINI_TABLE_FILE_H_ @@ -3228,23 +3692,102 @@ upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len, #ifndef UPB_MINI_TABLE_INTERNAL_FILE_H_ #define UPB_MINI_TABLE_INTERNAL_FILE_H_ - // Must be last. struct upb_MiniTableFile { - const struct upb_MiniTable** msgs; - const struct upb_MiniTableEnum** enums; - const struct upb_MiniTableExtension** exts; - int msg_count; - int enum_count; - int ext_count; + const struct upb_MiniTable** UPB_PRIVATE(msgs); + const struct upb_MiniTableEnum** UPB_PRIVATE(enums); + const struct upb_MiniTableExtension** UPB_PRIVATE(exts); + int UPB_PRIVATE(msg_count); + int UPB_PRIVATE(enum_count); + int UPB_PRIVATE(ext_count); }; +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE int UPB_PRIVATE(_upb_MiniTableFile_EnumCount)( + const struct upb_MiniTableFile* f) { + return f->UPB_PRIVATE(enum_count); +} + +UPB_INLINE int UPB_PRIVATE(_upb_MiniTableFile_ExtensionCount)( + const struct upb_MiniTableFile* f) { + return f->UPB_PRIVATE(ext_count); +} + +UPB_INLINE int UPB_PRIVATE(_upb_MiniTableFile_MessageCount)( + const struct upb_MiniTableFile* f) { + return f->UPB_PRIVATE(msg_count); +} + +UPB_INLINE const struct upb_MiniTableEnum* UPB_PRIVATE(_upb_MiniTableFile_Enum)( + const struct upb_MiniTableFile* f, int i) { + UPB_ASSERT(i < f->UPB_PRIVATE(enum_count)); + return f->UPB_PRIVATE(enums)[i]; +} + +UPB_INLINE const struct upb_MiniTableExtension* UPB_PRIVATE( + _upb_MiniTableFile_Extension)(const struct upb_MiniTableFile* f, int i) { + UPB_ASSERT(i < f->UPB_PRIVATE(ext_count)); + return f->UPB_PRIVATE(exts)[i]; +} + +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTableFile_Message)( + const struct upb_MiniTableFile* f, int i) { + UPB_ASSERT(i < f->UPB_PRIVATE(msg_count)); + return f->UPB_PRIVATE(msgs)[i]; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif /* UPB_MINI_TABLE_INTERNAL_FILE_H_ */ typedef struct upb_MiniTableFile upb_MiniTableFile; +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTableFile_Enum( + const upb_MiniTableFile* f, int i) { + return UPB_PRIVATE(_upb_MiniTableFile_Enum)(f, i); +} + +UPB_API_INLINE int upb_MiniTableFile_EnumCount(const upb_MiniTableFile* f) { + return UPB_PRIVATE(_upb_MiniTableFile_EnumCount)(f); +} + +UPB_API_INLINE const struct upb_MiniTableExtension* upb_MiniTableFile_Extension( + const upb_MiniTableFile* f, int i) { + return UPB_PRIVATE(_upb_MiniTableFile_Extension)(f, i); +} + +UPB_API_INLINE int upb_MiniTableFile_ExtensionCount( + const upb_MiniTableFile* f) { + return UPB_PRIVATE(_upb_MiniTableFile_ExtensionCount)(f); +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableFile_Message( + const upb_MiniTableFile* f, int i) { + return UPB_PRIVATE(_upb_MiniTableFile_Message)(f, i); +} + +UPB_API_INLINE int upb_MiniTableFile_MessageCount(const upb_MiniTableFile* f) { + return UPB_PRIVATE(_upb_MiniTableFile_MessageCount)(f); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + #endif /* UPB_MINI_TABLE_FILE_H_ */ // upb_decode: parsing into a upb_Message using a upb_MiniTable. @@ -4238,7 +4781,8 @@ typedef enum { google_protobuf_EDITION_2023 = 1000, google_protobuf_EDITION_99997_TEST_ONLY = 99997, google_protobuf_EDITION_99998_TEST_ONLY = 99998, - google_protobuf_EDITION_99999_TEST_ONLY = 99999 + google_protobuf_EDITION_99999_TEST_ONLY = 99999, + google_protobuf_EDITION_MAX = 2147483647 } google_protobuf_Edition; typedef enum { @@ -4279,8 +4823,8 @@ typedef enum { typedef enum { google_protobuf_FeatureSet_UTF8_VALIDATION_UNKNOWN = 0, - google_protobuf_FeatureSet_NONE = 1, - google_protobuf_FeatureSet_VERIFY = 2 + google_protobuf_FeatureSet_VERIFY = 2, + google_protobuf_FeatureSet_NONE = 3 } google_protobuf_FeatureSet_Utf8Validation; typedef enum { @@ -4457,7 +5001,7 @@ UPB_INLINE struct google_protobuf_FileDescriptorProto* google_protobuf_FileDescr } struct google_protobuf_FileDescriptorProto* sub = (struct google_protobuf_FileDescriptorProto*)_upb_Message_New(&google__protobuf__FileDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -4875,7 +5419,7 @@ UPB_INLINE bool google_protobuf_FileDescriptorProto_add_dependency(google_protob if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_mutable_message_type(google_protobuf_FileDescriptorProto* msg, size_t* size) { @@ -4901,7 +5445,7 @@ UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_FileDescripto } struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)_upb_Message_New(&google__protobuf__DescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_mutable_enum_type(google_protobuf_FileDescriptorProto* msg, size_t* size) { @@ -4927,7 +5471,7 @@ UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_FileDescr } struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)_upb_Message_New(&google__protobuf__EnumDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_mutable_service(google_protobuf_FileDescriptorProto* msg, size_t* size) { @@ -4953,7 +5497,7 @@ UPB_INLINE struct google_protobuf_ServiceDescriptorProto* google_protobuf_FileDe } struct google_protobuf_ServiceDescriptorProto* sub = (struct google_protobuf_ServiceDescriptorProto*)_upb_Message_New(&google__protobuf__ServiceDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_mutable_extension(google_protobuf_FileDescriptorProto* msg, size_t* size) { @@ -4979,7 +5523,7 @@ UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_FileDesc } struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_Message_New(&google__protobuf__FieldDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE void google_protobuf_FileDescriptorProto_set_options(google_protobuf_FileDescriptorProto *msg, google_protobuf_FileOptions* value) { @@ -5027,7 +5571,7 @@ UPB_INLINE bool google_protobuf_FileDescriptorProto_add_public_dependency(google if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_weak_dependency(google_protobuf_FileDescriptorProto* msg, size_t* size) { @@ -5051,7 +5595,7 @@ UPB_INLINE bool google_protobuf_FileDescriptorProto_add_weak_dependency(google_p if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto *msg, upb_StringView value) { @@ -5452,7 +5996,7 @@ UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_Descript } struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_Message_New(&google__protobuf__FieldDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_mutable_nested_type(google_protobuf_DescriptorProto* msg, size_t* size) { @@ -5478,7 +6022,7 @@ UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_DescriptorPro } struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)_upb_Message_New(&google__protobuf__DescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_mutable_enum_type(google_protobuf_DescriptorProto* msg, size_t* size) { @@ -5504,7 +6048,7 @@ UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_Descripto } struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)_upb_Message_New(&google__protobuf__EnumDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_mutable_extension_range(google_protobuf_DescriptorProto* msg, size_t* size) { @@ -5530,7 +6074,7 @@ UPB_INLINE struct google_protobuf_DescriptorProto_ExtensionRange* google_protobu } struct google_protobuf_DescriptorProto_ExtensionRange* sub = (struct google_protobuf_DescriptorProto_ExtensionRange*)_upb_Message_New(&google__protobuf__DescriptorProto__ExtensionRange_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_mutable_extension(google_protobuf_DescriptorProto* msg, size_t* size) { @@ -5556,7 +6100,7 @@ UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_Descript } struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)_upb_Message_New(&google__protobuf__FieldDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE void google_protobuf_DescriptorProto_set_options(google_protobuf_DescriptorProto *msg, google_protobuf_MessageOptions* value) { @@ -5594,7 +6138,7 @@ UPB_INLINE struct google_protobuf_OneofDescriptorProto* google_protobuf_Descript } struct google_protobuf_OneofDescriptorProto* sub = (struct google_protobuf_OneofDescriptorProto*)_upb_Message_New(&google__protobuf__OneofDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_mutable_reserved_range(google_protobuf_DescriptorProto* msg, size_t* size) { @@ -5620,7 +6164,7 @@ UPB_INLINE struct google_protobuf_DescriptorProto_ReservedRange* google_protobuf } struct google_protobuf_DescriptorProto_ReservedRange* sub = (struct google_protobuf_DescriptorProto_ReservedRange*)_upb_Message_New(&google__protobuf__DescriptorProto__ReservedRange_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE upb_StringView* google_protobuf_DescriptorProto_mutable_reserved_name(google_protobuf_DescriptorProto* msg, size_t* size) { @@ -5644,7 +6188,7 @@ UPB_INLINE bool google_protobuf_DescriptorProto_add_reserved_name(google_protobu if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } @@ -5988,7 +6532,7 @@ UPB_INLINE struct google_protobuf_ExtensionRangeOptions_Declaration* google_prot } struct google_protobuf_ExtensionRangeOptions_Declaration* sub = (struct google_protobuf_ExtensionRangeOptions_Declaration*)_upb_Message_New(&google__protobuf__ExtensionRangeOptions__Declaration_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE void google_protobuf_ExtensionRangeOptions_set_verification(google_protobuf_ExtensionRangeOptions *msg, int32_t value) { @@ -6030,7 +6574,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_Extension } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -6707,7 +7251,7 @@ UPB_INLINE struct google_protobuf_EnumValueDescriptorProto* google_protobuf_Enum } struct google_protobuf_EnumValueDescriptorProto* sub = (struct google_protobuf_EnumValueDescriptorProto*)_upb_Message_New(&google__protobuf__EnumValueDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE void google_protobuf_EnumDescriptorProto_set_options(google_protobuf_EnumDescriptorProto *msg, google_protobuf_EnumOptions* value) { @@ -6745,7 +7289,7 @@ UPB_INLINE struct google_protobuf_EnumDescriptorProto_EnumReservedRange* google_ } struct google_protobuf_EnumDescriptorProto_EnumReservedRange* sub = (struct google_protobuf_EnumDescriptorProto_EnumReservedRange*)_upb_Message_New(&google__protobuf__EnumDescriptorProto__EnumReservedRange_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE upb_StringView* google_protobuf_EnumDescriptorProto_mutable_reserved_name(google_protobuf_EnumDescriptorProto* msg, size_t* size) { @@ -6769,7 +7313,7 @@ UPB_INLINE bool google_protobuf_EnumDescriptorProto_add_reserved_name(google_pro if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } @@ -7080,7 +7624,7 @@ UPB_INLINE struct google_protobuf_MethodDescriptorProto* google_protobuf_Service } struct google_protobuf_MethodDescriptorProto* sub = (struct google_protobuf_MethodDescriptorProto*)_upb_Message_New(&google__protobuf__MethodDescriptorProto_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_options(google_protobuf_ServiceDescriptorProto *msg, google_protobuf_ServiceOptions* value) { @@ -7758,7 +8302,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FileOptio } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -7980,7 +8524,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MessageOp } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -8338,7 +8882,7 @@ UPB_INLINE bool google_protobuf_FieldOptions_add_targets(google_protobuf_FieldOp if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } UPB_INLINE google_protobuf_FieldOptions_EditionDefault** google_protobuf_FieldOptions_mutable_edition_defaults(google_protobuf_FieldOptions* msg, size_t* size) { @@ -8364,7 +8908,7 @@ UPB_INLINE struct google_protobuf_FieldOptions_EditionDefault* google_protobuf_F } struct google_protobuf_FieldOptions_EditionDefault* sub = (struct google_protobuf_FieldOptions_EditionDefault*)_upb_Message_New(&google__protobuf__FieldOptions__EditionDefault_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE void google_protobuf_FieldOptions_set_features(google_protobuf_FieldOptions *msg, google_protobuf_FeatureSet* value) { @@ -8402,7 +8946,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOpti } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -8604,7 +9148,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_OneofOpti } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -8788,7 +9332,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumOptio } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -8953,7 +9497,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumValue } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -9099,7 +9643,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ServiceOp } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -9264,7 +9808,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MethodOpt } struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)_upb_Message_New(&google__protobuf__UninterpretedOption_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -9454,7 +9998,7 @@ UPB_INLINE struct google_protobuf_UninterpretedOption_NamePart* google_protobuf_ } struct google_protobuf_UninterpretedOption_NamePart* sub = (struct google_protobuf_UninterpretedOption_NamePart*)_upb_Message_New(&google__protobuf__UninterpretedOption__NamePart_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE void google_protobuf_UninterpretedOption_set_identifier_value(google_protobuf_UninterpretedOption *msg, upb_StringView value) { @@ -9834,7 +10378,7 @@ UPB_INLINE struct google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* g } struct google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault* sub = (struct google_protobuf_FeatureSetDefaults_FeatureSetEditionDefault*)_upb_Message_New(&google__protobuf__FeatureSetDefaults__FeatureSetEditionDefault_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } UPB_INLINE void google_protobuf_FeatureSetDefaults_set_minimum_edition(google_protobuf_FeatureSetDefaults *msg, int32_t value) { @@ -10025,7 +10569,7 @@ UPB_INLINE struct google_protobuf_SourceCodeInfo_Location* google_protobuf_Sourc } struct google_protobuf_SourceCodeInfo_Location* sub = (struct google_protobuf_SourceCodeInfo_Location*)_upb_Message_New(&google__protobuf__SourceCodeInfo__Location_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -10227,7 +10771,7 @@ UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_path(google_protobuf if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_span(google_protobuf_SourceCodeInfo_Location* msg, size_t* size) { @@ -10251,7 +10795,7 @@ UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_span(google_protobuf if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_StringView value) { @@ -10283,7 +10827,7 @@ UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_leading_detached_com if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } @@ -10383,7 +10927,7 @@ UPB_INLINE struct google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_ } struct google_protobuf_GeneratedCodeInfo_Annotation* sub = (struct google_protobuf_GeneratedCodeInfo_Annotation*)_upb_Message_New(&google__protobuf__GeneratedCodeInfo__Annotation_msg_init, arena); if (!arr || !sub) return NULL; - _upb_Array_Set(arr, arr->size - 1, &sub, sizeof(sub)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &sub, sizeof(sub)); return sub; } @@ -10541,7 +11085,7 @@ UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_add_path(google_pro if (!arr || !_upb_Array_ResizeUninitialized(arr, arr->size + 1, arena)) { return false; } - _upb_Array_Set(arr, arr->size - 1, &val, sizeof(val)); + UPB_PRIVATE(_upb_Array_Set)(arr, arr->size - 1, &val, sizeof(val)); return true; } UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_StringView value) { @@ -10660,6 +11204,14 @@ UPB_API void upb_DefPool_Free(upb_DefPool* s); UPB_API upb_DefPool* upb_DefPool_New(void); +UPB_API const UPB_DESC(FeatureSetDefaults) * + upb_DefPool_FeatureSetDefaults(const upb_DefPool* s); + +UPB_API bool upb_DefPool_SetFeatureSetDefaults(upb_DefPool* s, + const char* serialized_defaults, + size_t serialized_len, + upb_Status* status); + UPB_API const upb_MessageDef* upb_DefPool_FindMessageByName( const upb_DefPool* s, const char* sym); @@ -10682,7 +11234,7 @@ const upb_FileDef* upb_DefPool_FindFileByNameWithSize(const upb_DefPool* s, const upb_FieldDef* upb_DefPool_FindExtensionByMiniTable( const upb_DefPool* s, const upb_MiniTableExtension* ext); -const upb_FieldDef* upb_DefPool_FindExtensionByName(const upb_DefPool* s, +UPB_API const upb_FieldDef* upb_DefPool_FindExtensionByName(const upb_DefPool* s, const char* sym); const upb_FieldDef* upb_DefPool_FindExtensionByNameWithSize( @@ -10705,7 +11257,7 @@ UPB_API const upb_FileDef* upb_DefPool_AddFile( upb_DefPool* s, const UPB_DESC(FileDescriptorProto) * file_proto, upb_Status* status); -const upb_ExtensionRegistry* upb_DefPool_ExtensionRegistry( +UPB_API const upb_ExtensionRegistry* upb_DefPool_ExtensionRegistry( const upb_DefPool* s); const upb_FieldDef** upb_DefPool_GetAllExtensions(const upb_DefPool* s, @@ -10751,6 +11303,7 @@ bool upb_EnumDef_MiniDescriptorEncode(const upb_EnumDef* e, upb_Arena* a, const char* upb_EnumDef_Name(const upb_EnumDef* e); const UPB_DESC(EnumOptions) * upb_EnumDef_Options(const upb_EnumDef* e); +const UPB_DESC(FeatureSet) * upb_EnumDef_ResolvedFeatures(const upb_EnumDef* e); upb_StringView upb_EnumDef_ReservedName(const upb_EnumDef* e, int i); int upb_EnumDef_ReservedNameCount(const upb_EnumDef* e); @@ -10789,6 +11342,8 @@ UPB_API const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v); UPB_API int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* v); const UPB_DESC(EnumValueOptions) * upb_EnumValueDef_Options(const upb_EnumValueDef* v); +const UPB_DESC(FeatureSet) * + upb_EnumValueDef_ResolvedFeatures(const upb_EnumValueDef* e); #ifdef __cplusplus } /* extern "C" */ @@ -10815,6 +11370,8 @@ int32_t upb_ExtensionRange_End(const upb_ExtensionRange* r); bool upb_ExtensionRange_HasOptions(const upb_ExtensionRange* r); const UPB_DESC(ExtensionRangeOptions) * upb_ExtensionRange_Options(const upb_ExtensionRange* r); +const UPB_DESC(FeatureSet) * + upb_ExtensionRange_ResolvedFeatures(const upb_ExtensionRange* e); #ifdef __cplusplus } /* extern "C" */ @@ -10876,6 +11433,8 @@ const upb_MiniTableField* upb_FieldDef_MiniTable(const upb_FieldDef* f); UPB_API const char* upb_FieldDef_Name(const upb_FieldDef* f); UPB_API uint32_t upb_FieldDef_Number(const upb_FieldDef* f); const UPB_DESC(FieldOptions) * upb_FieldDef_Options(const upb_FieldDef* f); +const UPB_DESC(FeatureSet) * + upb_FieldDef_ResolvedFeatures(const upb_FieldDef* f); UPB_API const upb_OneofDef* upb_FieldDef_RealContainingOneof( const upb_FieldDef* f); UPB_API upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f); @@ -10899,11 +11458,14 @@ UPB_API upb_FieldType upb_FieldDef_Type(const upb_FieldDef* f); extern "C" { #endif +UPB_API const char* upb_FileDef_EditionName(int edition); + const upb_FileDef* upb_FileDef_Dependency(const upb_FileDef* f, int i); int upb_FileDef_DependencyCount(const upb_FileDef* f); bool upb_FileDef_HasOptions(const upb_FileDef* f); UPB_API const char* upb_FileDef_Name(const upb_FileDef* f); const UPB_DESC(FileOptions) * upb_FileDef_Options(const upb_FileDef* f); +const UPB_DESC(FeatureSet) * upb_FileDef_ResolvedFeatures(const upb_FileDef* f); const char* upb_FileDef_Package(const upb_FileDef* f); UPB_DESC(Edition) upb_FileDef_Edition(const upb_FileDef* f); UPB_API const upb_DefPool* upb_FileDef_Pool(const upb_FileDef* f); @@ -11063,6 +11625,8 @@ int upb_MessageDef_RealOneofCount(const upb_MessageDef* m); const UPB_DESC(MessageOptions) * upb_MessageDef_Options(const upb_MessageDef* m); +const UPB_DESC(FeatureSet) * + upb_MessageDef_ResolvedFeatures(const upb_MessageDef* m); upb_StringView upb_MessageDef_ReservedName(const upb_MessageDef* m, int i); int upb_MessageDef_ReservedNameCount(const upb_MessageDef* m); @@ -11100,6 +11664,8 @@ int upb_MethodDef_Index(const upb_MethodDef* m); const upb_MessageDef* upb_MethodDef_InputType(const upb_MethodDef* m); const char* upb_MethodDef_Name(const upb_MethodDef* m); const UPB_DESC(MethodOptions) * upb_MethodDef_Options(const upb_MethodDef* m); +const UPB_DESC(FeatureSet) * + upb_MethodDef_ResolvedFeatures(const upb_MethodDef* m); const upb_MessageDef* upb_MethodDef_OutputType(const upb_MethodDef* m); bool upb_MethodDef_ServerStreaming(const upb_MethodDef* m); const upb_ServiceDef* upb_MethodDef_Service(const upb_MethodDef* m); @@ -11140,7 +11706,9 @@ const upb_FieldDef* upb_OneofDef_LookupNumber(const upb_OneofDef* o, uint32_t num); UPB_API const char* upb_OneofDef_Name(const upb_OneofDef* o); int upb_OneofDef_numfields(const upb_OneofDef* o); -const UPB_DESC(OneofOptions) * upb_OneofDef_Options(const upb_OneofDef* o); +const UPB_DESC(OneofOptions*) upb_OneofDef_Options(const upb_OneofDef* o); +const UPB_DESC(FeatureSet*) + upb_OneofDef_ResolvedFeatures(const upb_OneofDef* o); #ifdef __cplusplus } /* extern "C" */ @@ -11172,6 +11740,8 @@ int upb_ServiceDef_MethodCount(const upb_ServiceDef* s); const char* upb_ServiceDef_Name(const upb_ServiceDef* s); const UPB_DESC(ServiceOptions) * upb_ServiceDef_Options(const upb_ServiceDef* s); +const UPB_DESC(FeatureSet) * + upb_ServiceDef_ResolvedFeatures(const upb_ServiceDef* s); #ifdef __cplusplus } /* extern "C" */ @@ -11472,6 +12042,7 @@ double _upb_NoLocaleStrtod(const char *str, char **endptr); typedef struct _upb_MemBlock _upb_MemBlock; +// LINT.IfChange(struct_definition) struct upb_Arena { _upb_ArenaHead head; @@ -11500,6 +12071,7 @@ struct upb_Arena { // upb_Arena_SpaceAllocated(). UPB_ATOMIC(_upb_MemBlock*) blocks; }; +// LINT.ThenChange(//depot/google3/third_party/upb/bits/typescript/arena.ts) UPB_INLINE bool _upb_Arena_IsTaggedRefcount(uintptr_t parent_or_count) { return (parent_or_count & 1) == 1; @@ -11624,14 +12196,9 @@ UPB_INLINE bool _upb_NonAtomic_CompareExchangeStrongP(void* addr, #endif // UPB_PORT_ATOMIC_H_ -#ifndef UPB_WIRE_READER_H_ -#define UPB_WIRE_READER_H_ - - -#ifndef UPB_WIRE_INTERNAL_SWAP_H_ -#define UPB_WIRE_INTERNAL_SWAP_H_ +#ifndef UPB_MESSAGE_COPY_H_ +#define UPB_MESSAGE_COPY_H_ -#include // Must be last. @@ -11639,238 +12206,38 @@ UPB_INLINE bool _upb_NonAtomic_CompareExchangeStrongP(void* addr, extern "C" { #endif -UPB_INLINE bool _upb_IsLittleEndian(void) { - int x = 1; - return *(char*)&x == 1; -} +// Deep clones a message using the provided target arena. +upb_Message* upb_Message_DeepClone(const upb_Message* msg, + const upb_MiniTable* m, upb_Arena* arena); -UPB_INLINE uint32_t _upb_BigEndian_Swap32(uint32_t val) { - if (_upb_IsLittleEndian()) return val; +// Shallow clones a message using the provided target arena. +upb_Message* upb_Message_ShallowClone(const upb_Message* msg, + const upb_MiniTable* m, upb_Arena* arena); - return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | - ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24); -} - -UPB_INLINE uint64_t _upb_BigEndian_Swap64(uint64_t val) { - if (_upb_IsLittleEndian()) return val; - - return ((uint64_t)_upb_BigEndian_Swap32((uint32_t)val) << 32) | - _upb_BigEndian_Swap32((uint32_t)(val >> 32)); -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif +// Deep clones array contents. +upb_Array* upb_Array_DeepClone(const upb_Array* array, upb_CType value_type, + const upb_MiniTable* sub, upb_Arena* arena); +// Deep clones map contents. +upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type, + upb_CType value_type, + const upb_MiniTable* map_entry_table, + upb_Arena* arena); -#endif /* UPB_WIRE_INTERNAL_SWAP_H_ */ +// Deep copies the message from src to dst. +bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* m, upb_Arena* arena); -#ifndef UPB_WIRE_TYPES_H_ -#define UPB_WIRE_TYPES_H_ - -// A list of types as they are encoded on the wire. -typedef enum { - kUpb_WireType_Varint = 0, - kUpb_WireType_64Bit = 1, - kUpb_WireType_Delimited = 2, - kUpb_WireType_StartGroup = 3, - kUpb_WireType_EndGroup = 4, - kUpb_WireType_32Bit = 5 -} upb_WireType; - -#endif /* UPB_WIRE_TYPES_H_ */ - -// Must be last. - -#ifdef __cplusplus -extern "C" { -#endif - -// The upb_WireReader interface is suitable for general-purpose parsing of -// protobuf binary wire format. It is designed to be used along with -// upb_EpsCopyInputStream for buffering, and all parsing routines in this file -// assume that at least kUpb_EpsCopyInputStream_SlopBytes worth of data is -// available to read without any bounds checks. - -#define kUpb_WireReader_WireTypeMask 7 -#define kUpb_WireReader_WireTypeBits 3 - -typedef struct { - const char* ptr; - uint64_t val; -} _upb_WireReader_ReadLongVarintRet; - -_upb_WireReader_ReadLongVarintRet _upb_WireReader_ReadLongVarint( - const char* ptr, uint64_t val); - -static UPB_FORCEINLINE const char* _upb_WireReader_ReadVarint(const char* ptr, - uint64_t* val, - int maxlen, - uint64_t maxval) { - uint64_t byte = (uint8_t)*ptr; - if (UPB_LIKELY((byte & 0x80) == 0)) { - *val = (uint32_t)byte; - return ptr + 1; - } - const char* start = ptr; - _upb_WireReader_ReadLongVarintRet res = - _upb_WireReader_ReadLongVarint(ptr, byte); - if (!res.ptr || (maxlen < 10 && res.ptr - start > maxlen) || - res.val > maxval) { - return NULL; // Malformed. - } - *val = res.val; - return res.ptr; -} - -// Parses a tag into `tag`, and returns a pointer past the end of the tag, or -// NULL if there was an error in the tag data. -// -// REQUIRES: there must be at least 10 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -static UPB_FORCEINLINE const char* upb_WireReader_ReadTag(const char* ptr, - uint32_t* tag) { - uint64_t val; - ptr = _upb_WireReader_ReadVarint(ptr, &val, 5, UINT32_MAX); - if (!ptr) return NULL; - *tag = val; - return ptr; -} - -// Given a tag, returns the field number. -UPB_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag) { - return tag >> kUpb_WireReader_WireTypeBits; -} - -// Given a tag, returns the wire type. -UPB_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag) { - return tag & kUpb_WireReader_WireTypeMask; -} - -UPB_INLINE const char* upb_WireReader_ReadVarint(const char* ptr, - uint64_t* val) { - return _upb_WireReader_ReadVarint(ptr, val, 10, UINT64_MAX); -} - -// Skips data for a varint, returning a pointer past the end of the varint, or -// NULL if there was an error in the varint data. -// -// REQUIRES: there must be at least 10 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -UPB_INLINE const char* upb_WireReader_SkipVarint(const char* ptr) { - uint64_t val; - return upb_WireReader_ReadVarint(ptr, &val); -} - -// Reads a varint indicating the size of a delimited field into `size`, or -// NULL if there was an error in the varint data. -// -// REQUIRES: there must be at least 10 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -UPB_INLINE const char* upb_WireReader_ReadSize(const char* ptr, int* size) { - uint64_t size64; - ptr = upb_WireReader_ReadVarint(ptr, &size64); - if (!ptr || size64 >= INT32_MAX) return NULL; - *size = size64; - return ptr; -} - -// Reads a fixed32 field, performing byte swapping if necessary. -// -// REQUIRES: there must be at least 4 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -UPB_INLINE const char* upb_WireReader_ReadFixed32(const char* ptr, void* val) { - uint32_t uval; - memcpy(&uval, ptr, 4); - uval = _upb_BigEndian_Swap32(uval); - memcpy(val, &uval, 4); - return ptr + 4; -} - -// Reads a fixed64 field, performing byte swapping if necessary. -// -// REQUIRES: there must be at least 4 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -UPB_INLINE const char* upb_WireReader_ReadFixed64(const char* ptr, void* val) { - uint64_t uval; - memcpy(&uval, ptr, 8); - uval = _upb_BigEndian_Swap64(uval); - memcpy(val, &uval, 8); - return ptr + 8; -} - -const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag, - int depth_limit, - upb_EpsCopyInputStream* stream); - -// Skips data for a group, returning a pointer past the end of the group, or -// NULL if there was an error parsing the group. The `tag` argument should be -// the start group tag that begins the group. The `depth_limit` argument -// indicates how many levels of recursion the group is allowed to have before -// reporting a parse error (this limit exists to protect against stack -// overflow). -// -// TODO: evaluate how the depth_limit should be specified. Do users need -// control over this? -UPB_INLINE const char* upb_WireReader_SkipGroup( - const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { - return _upb_WireReader_SkipGroup(ptr, tag, 100, stream); -} - -UPB_INLINE const char* _upb_WireReader_SkipValue( - const char* ptr, uint32_t tag, int depth_limit, - upb_EpsCopyInputStream* stream) { - switch (upb_WireReader_GetWireType(tag)) { - case kUpb_WireType_Varint: - return upb_WireReader_SkipVarint(ptr); - case kUpb_WireType_32Bit: - return ptr + 4; - case kUpb_WireType_64Bit: - return ptr + 8; - case kUpb_WireType_Delimited: { - int size; - ptr = upb_WireReader_ReadSize(ptr, &size); - if (!ptr) return NULL; - ptr += size; - return ptr; - } - case kUpb_WireType_StartGroup: - return _upb_WireReader_SkipGroup(ptr, tag, depth_limit, stream); - case kUpb_WireType_EndGroup: - return NULL; // Should be handled before now. - default: - return NULL; // Unknown wire type. - } -} - -// Skips data for a wire value of any type, returning a pointer past the end of -// the data, or NULL if there was an error parsing the group. The `tag` argument -// should be the tag that was just parsed. The `depth_limit` argument indicates -// how many levels of recursion a group is allowed to have before reporting a -// parse error (this limit exists to protect against stack overflow). -// -// REQUIRES: there must be at least 10 bytes of data available at `ptr`. -// Bounds checks must be performed before calling this function, preferably -// by calling upb_EpsCopyInputStream_IsDone(). -// -// TODO: evaluate how the depth_limit should be specified. Do users need -// control over this? -UPB_INLINE const char* upb_WireReader_SkipValue( - const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { - return _upb_WireReader_SkipValue(ptr, tag, 100, stream); -} +// Shallow copies the message from src to dst. +void upb_Message_ShallowCopy(upb_Message* dst, const upb_Message* src, + const upb_MiniTable* m); #ifdef __cplusplus } /* extern "C" */ #endif -#endif // UPB_WIRE_READER_H_ +#endif // UPB_MESSAGE_COPY_H_ // EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// @@ -11943,7 +12310,7 @@ UPB_INLINE void _upb_mapsorter_init(_upb_mapsorter* s) { } UPB_INLINE void _upb_mapsorter_destroy(_upb_mapsorter* s) { - if (s->entries) free(s->entries); + if (s->entries) upb_gfree(s->entries); } UPB_INLINE bool _upb_sortedmap_next(_upb_mapsorter* s, const upb_Map* map, @@ -11984,10 +12351,6 @@ bool _upb_mapsorter_pushexts(_upb_mapsorter* s, #endif /* UPB_COLLECTIONS_INTERNAL_MAP_SORTER_H_ */ -#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_ -#define UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_ - - #ifndef UPB_MINI_DESCRIPTOR_INTERNAL_BASE92_H_ #define UPB_MINI_DESCRIPTOR_INTERNAL_BASE92_H_ @@ -12042,6 +12405,10 @@ UPB_INLINE const char* _upb_Base92_DecodeVarint(const char* ptr, #endif // UPB_MINI_DESCRIPTOR_INTERNAL_BASE92_H_ +#ifndef UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_ +#define UPB_MINI_DESCRIPTOR_INTERNAL_DECODER_H_ + + // Must be last. // upb_MdDecoder: used internally for decoding MiniDescriptors for messages, @@ -12325,6 +12692,10 @@ extern "C" { struct upb_DefBuilder { upb_DefPool* symtab; + upb_strtable feature_cache; // Caches features by identity. + UPB_DESC(FeatureSet*) legacy_features; // For computing legacy features. + char* tmp_buf; // Temporary buffer in tmp_arena. + size_t tmp_buf_size; // Size of temporary buffer. upb_FileDef* file; // File we are building. upb_Arena* arena; // Allocate defs here. upb_Arena* tmp_arena; // For temporary allocations. @@ -12417,6 +12788,25 @@ UPB_INLINE void _upb_DefBuilder_CheckIdentFull(upb_DefBuilder* ctx, if (!good) _upb_DefBuilder_CheckIdentSlow(ctx, name, true); } +// Returns true if the returned feature set is new and must be populated. +bool _upb_DefBuilder_GetOrCreateFeatureSet(upb_DefBuilder* ctx, + const UPB_DESC(FeatureSet*) parent, + upb_StringView key, + UPB_DESC(FeatureSet**) set); + +const UPB_DESC(FeatureSet*) + _upb_DefBuilder_DoResolveFeatures(upb_DefBuilder* ctx, + const UPB_DESC(FeatureSet*) parent, + const UPB_DESC(FeatureSet*) child, + bool is_implicit); + +UPB_INLINE const UPB_DESC(FeatureSet*) + _upb_DefBuilder_ResolveFeatures(upb_DefBuilder* ctx, + const UPB_DESC(FeatureSet*) parent, + const UPB_DESC(FeatureSet*) child) { + return _upb_DefBuilder_DoResolveFeatures(ctx, parent, child, false); +} + #ifdef __cplusplus } /* extern "C" */ #endif @@ -12439,10 +12829,11 @@ bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a); const upb_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e); // Allocate and initialize an array of |n| enum defs. -upb_EnumDef* _upb_EnumDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(EnumDescriptorProto) * const* protos, - const upb_MessageDef* containing_type); +upb_EnumDef* _upb_EnumDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(EnumDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + const upb_MessageDef* containing_type); #ifdef __cplusplus } /* extern "C" */ @@ -12466,7 +12857,8 @@ upb_EnumValueDef* _upb_EnumValueDef_At(const upb_EnumValueDef* v, int i); // Allocate and initialize an array of |n| enum value defs owned by |e|. upb_EnumValueDef* _upb_EnumValueDefs_New( upb_DefBuilder* ctx, const char* prefix, int n, - const UPB_DESC(EnumValueDescriptorProto) * const* protos, upb_EnumDef* e, + const UPB_DESC(EnumValueDescriptorProto*) const* protos, + const UPB_DESC(FeatureSet*) parent_features, upb_EnumDef* e, bool* is_sorted); const upb_EnumValueDef** _upb_EnumValueDefs_Sorted(const upb_EnumValueDef* v, @@ -12503,16 +12895,19 @@ void _upb_FieldDef_BuildMiniTableExtension(upb_DefBuilder* ctx, const upb_FieldDef* f); // Allocate and initialize an array of |n| extensions (field defs). -upb_FieldDef* _upb_Extensions_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(FieldDescriptorProto) * const* protos, const char* prefix, - upb_MessageDef* m); +upb_FieldDef* _upb_Extensions_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(FieldDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + const char* prefix, upb_MessageDef* m); // Allocate and initialize an array of |n| field defs. -upb_FieldDef* _upb_FieldDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(FieldDescriptorProto) * const* protos, const char* prefix, - upb_MessageDef* m, bool* is_sorted); +upb_FieldDef* _upb_FieldDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(FieldDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + const char* prefix, upb_MessageDef* m, + bool* is_sorted); // Allocate and return a list of pointers to the |n| field defs in |ff|, // sorted by field number. @@ -12577,9 +12972,12 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx, void _upb_MessageDef_Resolve(upb_DefBuilder* ctx, upb_MessageDef* m); // Allocate and initialize an array of |n| message defs. -upb_MessageDef* _upb_MessageDefs_New( - upb_DefBuilder* ctx, int n, const UPB_DESC(DescriptorProto) * const* protos, - const upb_MessageDef* containing_type); +upb_MessageDef* _upb_MessageDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(DescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) + parent_features, + const upb_MessageDef* containing_type); #ifdef __cplusplus } /* extern "C" */ @@ -12601,9 +12999,11 @@ extern "C" { upb_ServiceDef* _upb_ServiceDef_At(const upb_ServiceDef* s, int i); // Allocate and initialize an array of |n| service defs. -upb_ServiceDef* _upb_ServiceDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(ServiceDescriptorProto) * const* protos); +upb_ServiceDef* _upb_ServiceDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(ServiceDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) + parent_features); #ifdef __cplusplus } /* extern "C" */ @@ -12612,6 +13012,20 @@ upb_ServiceDef* _upb_ServiceDefs_New( #endif /* UPB_REFLECTION_SERVICE_DEF_INTERNAL_H_ */ +#ifndef UPB_REFLECTION_UPB_EDITION_DEFAULTS_H_ +#define UPB_REFLECTION_UPB_EDITION_DEFAULTS_H_ + +// This file contains the serialized FeatureSetDefaults object for +// language-independent features and (possibly at some point) for upb-specific +// features. This is used for feature resolution under Editions. +// NOLINTBEGIN +// clang-format off +#define UPB_INTERNAL_UPB_EDITION_DEFAULTS "\n\021\022\014\010\001\020\002\030\002 \003(\0010\002\030\346\007\n\021\022\014\010\002\020\001\030\001 \002(\0010\001\030\347\007\n\021\022\014\010\001\020\001\030\001 \002(\0010\001\030\350\007 \346\007(\350\007" +// clang-format on +// NOLINTEND + +#endif // UPB_REFLECTION_UPB_EDITION_DEFAULTS_H_ + #ifndef UPB_REFLECTION_DESC_STATE_INTERNAL_H_ #define UPB_REFLECTION_DESC_STATE_INTERNAL_H_ @@ -12684,7 +13098,7 @@ upb_EnumReservedRange* _upb_EnumReservedRange_At(const upb_EnumReservedRange* r, // Allocate and initialize an array of |n| reserved ranges owned by |e|. upb_EnumReservedRange* _upb_EnumReservedRanges_New( upb_DefBuilder* ctx, int n, - const UPB_DESC(EnumDescriptorProto_EnumReservedRange) * const* protos, + const UPB_DESC(EnumDescriptorProto_EnumReservedRange*) const* protos, const upb_EnumDef* e); #ifdef __cplusplus @@ -12732,8 +13146,8 @@ upb_ExtensionRange* _upb_ExtensionRange_At(const upb_ExtensionRange* r, int i); // Allocate and initialize an array of |n| extension ranges owned by |m|. upb_ExtensionRange* _upb_ExtensionRanges_New( upb_DefBuilder* ctx, int n, - const UPB_DESC(DescriptorProto_ExtensionRange) * const* protos, - const upb_MessageDef* m); + const UPB_DESC(DescriptorProto_ExtensionRange*) const* protos, + const UPB_DESC(FeatureSet*) parent_features, const upb_MessageDef* m); #ifdef __cplusplus } /* extern "C" */ @@ -12757,9 +13171,11 @@ void _upb_OneofDef_Insert(upb_DefBuilder* ctx, upb_OneofDef* o, const upb_FieldDef* f, const char* name, size_t size); // Allocate and initialize an array of |n| oneof defs owned by |m|. -upb_OneofDef* _upb_OneofDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(OneofDescriptorProto) * const* protos, upb_MessageDef* m); +upb_OneofDef* _upb_OneofDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(OneofDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + upb_MessageDef* m); size_t _upb_OneofDefs_Finalize(upb_DefBuilder* ctx, upb_MessageDef* m); @@ -12831,9 +13247,11 @@ extern "C" { upb_MethodDef* _upb_MethodDef_At(const upb_MethodDef* m, int i); // Allocate and initialize an array of |n| method defs owned by |s|. -upb_MethodDef* _upb_MethodDefs_New( - upb_DefBuilder* ctx, int n, - const UPB_DESC(MethodDescriptorProto) * const* protos, upb_ServiceDef* s); +upb_MethodDef* _upb_MethodDefs_New(upb_DefBuilder* ctx, int n, + const UPB_DESC(MethodDescriptorProto*) + const* protos, + const UPB_DESC(FeatureSet*) parent_features, + upb_ServiceDef* s); #ifdef __cplusplus } /* extern "C" */ @@ -12933,12 +13351,12 @@ non_ascii: const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, const upb_Message* msg, - const upb_MiniTable* l); + const upb_MiniTable* m); /* x86-64 pointers always have the high 16 bits matching. So we can shift * left 8 and right 8 without loss of information. */ UPB_INLINE intptr_t decode_totable(const upb_MiniTable* tablep) { - return ((intptr_t)tablep << 8) | tablep->table_mask; + return ((intptr_t)tablep << 8) | tablep->UPB_PRIVATE(table_mask); } UPB_INLINE const upb_MiniTable* decode_totablep(intptr_t table) { @@ -12959,8 +13377,8 @@ UPB_INLINE const char* _upb_Decoder_BufferFlipCallback( if (!old_end) _upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed); if (d->unknown) { - if (!_upb_Message_AddUnknown(d->unknown_msg, d->unknown, - old_end - d->unknown, &d->arena)) { + if (!UPB_PRIVATE(_upb_Message_AddUnknown)( + d->unknown_msg, d->unknown, old_end - d->unknown, &d->arena)) { _upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); } d->unknown = new_start; @@ -12979,9 +13397,9 @@ const char* _upb_FastDecoder_TagDispatch(upb_Decoder* d, const char* ptr, size_t idx = tag & mask; UPB_ASSUME((idx & 7) == 0); idx >>= 3; - data = table_p->fasttable[idx].field_data ^ tag; - UPB_MUSTTAIL return table_p->fasttable[idx].field_parser(d, ptr, msg, table, - hasbits, data); + data = table_p->UPB_PRIVATE(fasttable)[idx].field_data ^ tag; + UPB_MUSTTAIL return table_p->UPB_PRIVATE(fasttable)[idx].field_parser( + d, ptr, msg, table, hasbits, data); } #endif @@ -12994,6 +13412,254 @@ UPB_INLINE uint32_t _upb_FastDecoder_LoadTag(const char* ptr) { #endif /* UPB_WIRE_INTERNAL_DECODE_H_ */ +#ifndef UPB_WIRE_INTERNAL_SWAP_H_ +#define UPB_WIRE_INTERNAL_SWAP_H_ + +#include + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE bool _upb_IsLittleEndian(void) { + int x = 1; + return *(char*)&x == 1; +} + +UPB_INLINE uint32_t _upb_BigEndian_Swap32(uint32_t val) { + if (_upb_IsLittleEndian()) return val; + + return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | + ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24); +} + +UPB_INLINE uint64_t _upb_BigEndian_Swap64(uint64_t val) { + if (_upb_IsLittleEndian()) return val; + + return ((uint64_t)_upb_BigEndian_Swap32((uint32_t)val) << 32) | + _upb_BigEndian_Swap32((uint32_t)(val >> 32)); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_WIRE_INTERNAL_SWAP_H_ */ + +#ifndef UPB_WIRE_READER_H_ +#define UPB_WIRE_READER_H_ + + +#ifndef UPB_WIRE_TYPES_H_ +#define UPB_WIRE_TYPES_H_ + +// A list of types as they are encoded on the wire. +typedef enum { + kUpb_WireType_Varint = 0, + kUpb_WireType_64Bit = 1, + kUpb_WireType_Delimited = 2, + kUpb_WireType_StartGroup = 3, + kUpb_WireType_EndGroup = 4, + kUpb_WireType_32Bit = 5 +} upb_WireType; + +#endif /* UPB_WIRE_TYPES_H_ */ + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// The upb_WireReader interface is suitable for general-purpose parsing of +// protobuf binary wire format. It is designed to be used along with +// upb_EpsCopyInputStream for buffering, and all parsing routines in this file +// assume that at least kUpb_EpsCopyInputStream_SlopBytes worth of data is +// available to read without any bounds checks. + +#define kUpb_WireReader_WireTypeMask 7 +#define kUpb_WireReader_WireTypeBits 3 + +typedef struct { + const char* ptr; + uint64_t val; +} _upb_WireReader_ReadLongVarintRet; + +_upb_WireReader_ReadLongVarintRet _upb_WireReader_ReadLongVarint( + const char* ptr, uint64_t val); + +static UPB_FORCEINLINE const char* _upb_WireReader_ReadVarint(const char* ptr, + uint64_t* val, + int maxlen, + uint64_t maxval) { + uint64_t byte = (uint8_t)*ptr; + if (UPB_LIKELY((byte & 0x80) == 0)) { + *val = (uint32_t)byte; + return ptr + 1; + } + const char* start = ptr; + _upb_WireReader_ReadLongVarintRet res = + _upb_WireReader_ReadLongVarint(ptr, byte); + if (!res.ptr || (maxlen < 10 && res.ptr - start > maxlen) || + res.val > maxval) { + return NULL; // Malformed. + } + *val = res.val; + return res.ptr; +} + +// Parses a tag into `tag`, and returns a pointer past the end of the tag, or +// NULL if there was an error in the tag data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +static UPB_FORCEINLINE const char* upb_WireReader_ReadTag(const char* ptr, + uint32_t* tag) { + uint64_t val; + ptr = _upb_WireReader_ReadVarint(ptr, &val, 5, UINT32_MAX); + if (!ptr) return NULL; + *tag = val; + return ptr; +} + +// Given a tag, returns the field number. +UPB_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag) { + return tag >> kUpb_WireReader_WireTypeBits; +} + +// Given a tag, returns the wire type. +UPB_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag) { + return tag & kUpb_WireReader_WireTypeMask; +} + +UPB_INLINE const char* upb_WireReader_ReadVarint(const char* ptr, + uint64_t* val) { + return _upb_WireReader_ReadVarint(ptr, val, 10, UINT64_MAX); +} + +// Skips data for a varint, returning a pointer past the end of the varint, or +// NULL if there was an error in the varint data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_SkipVarint(const char* ptr) { + uint64_t val; + return upb_WireReader_ReadVarint(ptr, &val); +} + +// Reads a varint indicating the size of a delimited field into `size`, or +// NULL if there was an error in the varint data. +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadSize(const char* ptr, int* size) { + uint64_t size64; + ptr = upb_WireReader_ReadVarint(ptr, &size64); + if (!ptr || size64 >= INT32_MAX) return NULL; + *size = size64; + return ptr; +} + +// Reads a fixed32 field, performing byte swapping if necessary. +// +// REQUIRES: there must be at least 4 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadFixed32(const char* ptr, void* val) { + uint32_t uval; + memcpy(&uval, ptr, 4); + uval = _upb_BigEndian_Swap32(uval); + memcpy(val, &uval, 4); + return ptr + 4; +} + +// Reads a fixed64 field, performing byte swapping if necessary. +// +// REQUIRES: there must be at least 4 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +UPB_INLINE const char* upb_WireReader_ReadFixed64(const char* ptr, void* val) { + uint64_t uval; + memcpy(&uval, ptr, 8); + uval = _upb_BigEndian_Swap64(uval); + memcpy(val, &uval, 8); + return ptr + 8; +} + +const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag, + int depth_limit, + upb_EpsCopyInputStream* stream); + +// Skips data for a group, returning a pointer past the end of the group, or +// NULL if there was an error parsing the group. The `tag` argument should be +// the start group tag that begins the group. The `depth_limit` argument +// indicates how many levels of recursion the group is allowed to have before +// reporting a parse error (this limit exists to protect against stack +// overflow). +// +// TODO: evaluate how the depth_limit should be specified. Do users need +// control over this? +UPB_INLINE const char* upb_WireReader_SkipGroup( + const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { + return _upb_WireReader_SkipGroup(ptr, tag, 100, stream); +} + +UPB_INLINE const char* _upb_WireReader_SkipValue( + const char* ptr, uint32_t tag, int depth_limit, + upb_EpsCopyInputStream* stream) { + switch (upb_WireReader_GetWireType(tag)) { + case kUpb_WireType_Varint: + return upb_WireReader_SkipVarint(ptr); + case kUpb_WireType_32Bit: + return ptr + 4; + case kUpb_WireType_64Bit: + return ptr + 8; + case kUpb_WireType_Delimited: { + int size; + ptr = upb_WireReader_ReadSize(ptr, &size); + if (!ptr) return NULL; + ptr += size; + return ptr; + } + case kUpb_WireType_StartGroup: + return _upb_WireReader_SkipGroup(ptr, tag, depth_limit, stream); + case kUpb_WireType_EndGroup: + return NULL; // Should be handled before now. + default: + return NULL; // Unknown wire type. + } +} + +// Skips data for a wire value of any type, returning a pointer past the end of +// the data, or NULL if there was an error parsing the group. The `tag` argument +// should be the tag that was just parsed. The `depth_limit` argument indicates +// how many levels of recursion a group is allowed to have before reporting a +// parse error (this limit exists to protect against stack overflow). +// +// REQUIRES: there must be at least 10 bytes of data available at `ptr`. +// Bounds checks must be performed before calling this function, preferably +// by calling upb_EpsCopyInputStream_IsDone(). +// +// TODO: evaluate how the depth_limit should be specified. Do users need +// control over this? +UPB_INLINE const char* upb_WireReader_SkipValue( + const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { + return _upb_WireReader_SkipValue(ptr, tag, 100, stream); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // UPB_WIRE_READER_H_ + // This should #undef all macros #defined in def.inc #undef UPB_SIZE @@ -13038,7 +13704,9 @@ UPB_INLINE uint32_t _upb_FastDecoder_LoadTag(const char* ptr) { #undef UPB_GNUC_MIN #undef UPB_DESCRIPTOR_UPB_H_FILENAME #undef UPB_DESC +#undef UPB_DESC_MINITABLE #undef UPB_IS_GOOGLE3 #undef UPB_ATOMIC #undef UPB_USE_C11_ATOMICS #undef UPB_PRIVATE +#undef UPB_ONLYBITS diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec index 8a292af288..e3770be416 100644 --- a/ruby/google-protobuf.gemspec +++ b/ruby/google-protobuf.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = "google-protobuf" - s.version = "3.24.0" + s.version = "3.25.0" git_tag = "v#{s.version.to_s.sub('.rc.', '-rc')}" # Converts X.Y.Z.rc.N to vX.Y.Z-rcN, used for the git tag s.licenses = ["BSD-3-Clause"] s.summary = "Protocol Buffers" diff --git a/ruby/lib/google/BUILD.bazel b/ruby/lib/google/BUILD.bazel index 18f1c18444..8af2fa8e88 100644 --- a/ruby/lib/google/BUILD.bazel +++ b/ruby/lib/google/BUILD.bazel @@ -76,9 +76,12 @@ ruby_library( "//ruby:linux_ffi_enabled": ["libprotobuf_c_ffi.so"], "//conditions:default": [], }), - includes = ["ruby/lib"], + includes = [ + "ruby", + "ruby/lib", + ], visibility = ["//ruby:__pkg__"], - deps = ["//:well_known_ruby_protos"] + select({ + deps = ["//ruby:well_known_ruby_protos"] + select({ "//ruby:ffi_enabled": [ "@protobuf_bundle//:ffi", "@protobuf_bundle//:ffi-compiler", diff --git a/ruby/lib/google/protobuf/ffi/descriptor.rb b/ruby/lib/google/protobuf/ffi/descriptor.rb index c878eb5b77..25d226abd1 100644 --- a/ruby/lib/google/protobuf/ffi/descriptor.rb +++ b/ruby/lib/google/protobuf/ffi/descriptor.rb @@ -95,6 +95,15 @@ module Google @msg_class ||= build_message_class end + def options + @options ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.message_options(self, size_ptr, temporary_arena) + Google::Protobuf::MessageOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze).send(:internal_deep_freeze) + end + end + private extend Google::Protobuf::Internal::Convert @@ -129,6 +138,7 @@ module Google message = OBJECT_CACHE.get(msg.address) if message.nil? message = descriptor.msgclass.send(:private_constructor, arena, msg: msg) + message.send :internal_deep_freeze if frozen? end message end @@ -146,6 +156,7 @@ module Google attach_function :get_message_fullname, :upb_MessageDef_FullName, [Descriptor], :string attach_function :get_mini_table, :upb_MessageDef_MiniTable, [Descriptor], MiniTable.ptr attach_function :oneof_count, :upb_MessageDef_OneofCount, [Descriptor], :int + attach_function :message_options, :Descriptor_serialized_options, [Descriptor, :pointer, Internal::Arena], :pointer attach_function :get_well_known_type, :upb_MessageDef_WellKnownType, [Descriptor], WellKnown attach_function :message_def_syntax, :upb_MessageDef_Syntax, [Descriptor], Syntax attach_function :find_msg_def_by_name, :upb_MessageDef_FindByNameWithSize, [Descriptor, :string, :size_t, :FieldDefPointer, :OneofDefPointer], :bool diff --git a/ruby/lib/google/protobuf/ffi/descriptor_pool.rb b/ruby/lib/google/protobuf/ffi/descriptor_pool.rb index bd9c96df99..96c7d09417 100644 --- a/ruby/lib/google/protobuf/ffi/descriptor_pool.rb +++ b/ruby/lib/google/protobuf/ffi/descriptor_pool.rb @@ -9,13 +9,16 @@ module Google module Protobuf class FFI # DefPool - attach_function :add_serialized_file, :upb_DefPool_AddFile, [:DefPool, :FileDescriptorProto, Status.by_ref], :FileDef - attach_function :free_descriptor_pool, :upb_DefPool_Free, [:DefPool], :void - attach_function :create_descriptor_pool,:upb_DefPool_New, [], :DefPool - attach_function :lookup_enum, :upb_DefPool_FindEnumByName, [:DefPool, :string], EnumDescriptor - attach_function :lookup_msg, :upb_DefPool_FindMessageByName, [:DefPool, :string], Descriptor - # FileDescriptorProto - attach_function :parse, :FileDescriptorProto_parse, [:binary_string, :size_t], :FileDescriptorProto + attach_function :add_serialized_file, :upb_DefPool_AddFile, [:DefPool, :FileDescriptorProto, Status.by_ref], :FileDef + attach_function :free_descriptor_pool, :upb_DefPool_Free, [:DefPool], :void + attach_function :create_descriptor_pool,:upb_DefPool_New, [], :DefPool + attach_function :get_extension_registry,:upb_DefPool_ExtensionRegistry, [:DefPool], :ExtensionRegistry + attach_function :lookup_enum, :upb_DefPool_FindEnumByName, [:DefPool, :string], EnumDescriptor + attach_function :lookup_extension, :upb_DefPool_FindExtensionByName,[:DefPool, :string], FieldDescriptor + attach_function :lookup_msg, :upb_DefPool_FindMessageByName, [:DefPool, :string], Descriptor + + # FileDescriptorProto + attach_function :parse, :FileDescriptorProto_parse, [:binary_string, :size_t, Internal::Arena], :FileDescriptorProto end class DescriptorPool attr :descriptor_pool @@ -35,7 +38,8 @@ module Google memBuf = ::FFI::MemoryPointer.new(:char, file_contents.bytesize) # Insert the data memBuf.put_bytes(0, file_contents) - file_descriptor_proto = Google::Protobuf::FFI.parse memBuf, file_contents.bytesize + temporary_arena = Google::Protobuf::FFI.create_arena + file_descriptor_proto = Google::Protobuf::FFI.parse memBuf, file_contents.bytesize, temporary_arena raise ArgumentError.new("Unable to parse FileDescriptorProto") if file_descriptor_proto.null? status = Google::Protobuf::FFI::Status.new @@ -49,7 +53,8 @@ module Google def lookup name Google::Protobuf::FFI.lookup_msg(@descriptor_pool, name) || - Google::Protobuf::FFI.lookup_enum(@descriptor_pool, name) + Google::Protobuf::FFI.lookup_enum(@descriptor_pool, name) || + Google::Protobuf::FFI.lookup_extension(@descriptor_pool, name) end def self.generated_pool diff --git a/ruby/lib/google/protobuf/ffi/enum_descriptor.rb b/ruby/lib/google/protobuf/ffi/enum_descriptor.rb index 773cf7305e..a1f4fefcd5 100644 --- a/ruby/lib/google/protobuf/ffi/enum_descriptor.rb +++ b/ruby/lib/google/protobuf/ffi/enum_descriptor.rb @@ -19,7 +19,7 @@ module Google prepend Google::Protobuf::Internal::TypeSafety include Google::Protobuf::Internal::PointerHelper - # @param value [Arena] Arena to convert to an FFI native type + # @param value [EnumDescriptor] EnumDescriptor to convert to an FFI native type # @param _ [Object] Unused def to_native(value, _) value.instance_variable_get(:@enum_def) || ::FFI::Pointer::NULL @@ -79,6 +79,15 @@ module Google @module end + def options + @options ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.enum_options(self, size_ptr, temporary_arena) + Google::Protobuf::EnumOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze).send(:internal_deep_freeze) + end + end + private def initialize(enum_def, descriptor_pool) @@ -152,6 +161,7 @@ module Google attach_function :enum_value_by_name, :upb_EnumDef_FindValueByNameWithSize,[EnumDescriptor, :string, :size_t], :EnumValueDef attach_function :enum_value_by_number, :upb_EnumDef_FindValueByNumber, [EnumDescriptor, :int], :EnumValueDef attach_function :get_enum_fullname, :upb_EnumDef_FullName, [EnumDescriptor], :string + attach_function :enum_options, :EnumDescriptor_serialized_options, [EnumDescriptor, :pointer, Internal::Arena], :pointer attach_function :enum_value_by_index, :upb_EnumDef_Value, [EnumDescriptor, :int], :EnumValueDef attach_function :enum_value_count, :upb_EnumDef_ValueCount, [EnumDescriptor], :int attach_function :enum_name, :upb_EnumValueDef_Name, [:EnumValueDef], :string diff --git a/ruby/lib/google/protobuf/ffi/field_descriptor.rb b/ruby/lib/google/protobuf/ffi/field_descriptor.rb index 800661bbd8..d7c45da193 100644 --- a/ruby/lib/google/protobuf/ffi/field_descriptor.rb +++ b/ruby/lib/google/protobuf/ffi/field_descriptor.rb @@ -206,6 +206,15 @@ module Google end end + def options + @options ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.field_options(self, size_ptr, temporary_arena) + Google::Protobuf::FieldOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze).send(:internal_deep_freeze) + end + end + private def initialize(field_def, descriptor_pool) @@ -289,21 +298,22 @@ module Google attach_function :get_field_by_number, :upb_MessageDef_FindFieldByNumber, [Descriptor, :uint32_t], FieldDescriptor # FieldDescriptor - attach_function :get_containing_message_def, :upb_FieldDef_ContainingType, [FieldDescriptor], Descriptor - attach_function :get_c_type, :upb_FieldDef_CType, [FieldDescriptor], CType - attach_function :get_default, :upb_FieldDef_Default, [FieldDescriptor], MessageValue.by_value - attach_function :get_subtype_as_enum, :upb_FieldDef_EnumSubDef, [FieldDescriptor], EnumDescriptor - attach_function :get_has_presence, :upb_FieldDef_HasPresence, [FieldDescriptor], :bool - attach_function :is_map, :upb_FieldDef_IsMap, [FieldDescriptor], :bool - attach_function :is_repeated, :upb_FieldDef_IsRepeated, [FieldDescriptor], :bool - attach_function :is_sub_message, :upb_FieldDef_IsSubMessage, [FieldDescriptor], :bool - attach_function :get_json_name, :upb_FieldDef_JsonName, [FieldDescriptor], :string - attach_function :get_label, :upb_FieldDef_Label, [FieldDescriptor], Label - attach_function :get_subtype_as_message, :upb_FieldDef_MessageSubDef, [FieldDescriptor], Descriptor - attach_function :get_full_name, :upb_FieldDef_Name, [FieldDescriptor], :string - attach_function :get_number, :upb_FieldDef_Number, [FieldDescriptor], :uint32_t - attach_function :get_type, :upb_FieldDef_Type, [FieldDescriptor], FieldType - attach_function :file_def_by_raw_field_def, :upb_FieldDef_File, [:pointer], :FileDef + attach_function :field_options, :FieldDescriptor_serialized_options, [FieldDescriptor, :pointer, Internal::Arena], :pointer + attach_function :get_containing_message_def, :upb_FieldDef_ContainingType, [FieldDescriptor], Descriptor + attach_function :get_c_type, :upb_FieldDef_CType, [FieldDescriptor], CType + attach_function :get_default, :upb_FieldDef_Default, [FieldDescriptor], MessageValue.by_value + attach_function :get_subtype_as_enum, :upb_FieldDef_EnumSubDef, [FieldDescriptor], EnumDescriptor + attach_function :get_has_presence, :upb_FieldDef_HasPresence, [FieldDescriptor], :bool + attach_function :is_map, :upb_FieldDef_IsMap, [FieldDescriptor], :bool + attach_function :is_repeated, :upb_FieldDef_IsRepeated, [FieldDescriptor], :bool + attach_function :is_sub_message, :upb_FieldDef_IsSubMessage, [FieldDescriptor], :bool + attach_function :get_json_name, :upb_FieldDef_JsonName, [FieldDescriptor], :string + attach_function :get_label, :upb_FieldDef_Label, [FieldDescriptor], Label + attach_function :get_subtype_as_message, :upb_FieldDef_MessageSubDef, [FieldDescriptor], Descriptor + attach_function :get_full_name, :upb_FieldDef_Name, [FieldDescriptor], :string + attach_function :get_number, :upb_FieldDef_Number, [FieldDescriptor], :uint32_t + attach_function :get_type, :upb_FieldDef_Type, [FieldDescriptor], FieldType + attach_function :file_def_by_raw_field_def, :upb_FieldDef_File, [:pointer], :FileDef end end end diff --git a/ruby/lib/google/protobuf/ffi/file_descriptor.rb b/ruby/lib/google/protobuf/ffi/file_descriptor.rb index 0a465ecdbf..291ac4f3e4 100644 --- a/ruby/lib/google/protobuf/ffi/file_descriptor.rb +++ b/ruby/lib/google/protobuf/ffi/file_descriptor.rb @@ -12,7 +12,9 @@ module Google attach_function :file_def_name, :upb_FileDef_Name, [:FileDef], :string attach_function :file_def_syntax, :upb_FileDef_Syntax, [:FileDef], Syntax attach_function :file_def_pool, :upb_FileDef_Pool, [:FileDef], :DefPool + attach_function :file_options, :FileDescriptor_serialized_options, [:FileDef, :pointer, Internal::Arena], :pointer end + class FileDescriptor attr :descriptor_pool, :file_def @@ -43,6 +45,15 @@ module Google def name Google::Protobuf::FFI.file_def_name(@file_def) end + + def options + @options ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.file_options(@file_def, size_ptr, temporary_arena) + Google::Protobuf::FileOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze).send(:internal_deep_freeze) + end + end end end end diff --git a/ruby/lib/google/protobuf/ffi/map.rb b/ruby/lib/google/protobuf/ffi/map.rb index 50c917e63f..61abbe53b0 100644 --- a/ruby/lib/google/protobuf/ffi/map.rb +++ b/ruby/lib/google/protobuf/ffi/map.rb @@ -269,6 +269,17 @@ module Google include Google::Protobuf::Internal::Convert + def internal_deep_freeze + freeze + if value_type == :message + internal_iterator do |iterator| + value_message_value = Google::Protobuf::FFI.map_value(@map_ptr, iterator) + convert_upb_to_ruby(value_message_value, value_type, descriptor, arena).send :internal_deep_freeze + end + end + self + end + def internal_iterator iter = ::FFI::MemoryPointer.new(:size_t, 1) iter.write(:size_t, Google::Protobuf::FFI::Upb_Map_Begin) diff --git a/ruby/lib/google/protobuf/ffi/message.rb b/ruby/lib/google/protobuf/ffi/message.rb index d53d437819..39eb403853 100644 --- a/ruby/lib/google/protobuf/ffi/message.rb +++ b/ruby/lib/google/protobuf/ffi/message.rb @@ -19,7 +19,7 @@ module Google attach_function :encode_message, :upb_Encode, [:Message, MiniTable.by_ref, :size_t, Internal::Arena, :pointer, :pointer], EncodeStatus attach_function :json_decode_message, :upb_JsonDecode, [:binary_string, :size_t, :Message, Descriptor, :DefPool, :int, Internal::Arena, Status.by_ref], :bool attach_function :json_encode_message, :upb_JsonEncode, [:Message, Descriptor, :DefPool, :int, :binary_string, :size_t, Status.by_ref], :size_t - attach_function :decode_message, :upb_Decode, [:binary_string, :size_t, :Message, MiniTable.by_ref, :ExtensionRegistry, :int, Internal::Arena], DecodeStatus + attach_function :decode_message, :upb_Decode, [:binary_string, :size_t, :Message, MiniTable.by_ref, :ExtensionRegistry, :int, Internal::Arena], DecodeStatus attach_function :get_mutable_message, :upb_Message_Mutable, [:Message, FieldDescriptor, Internal::Arena], MutableMessageValue.by_value attach_function :get_message_which_oneof, :upb_Message_WhichOneof, [:Message, OneofDescriptor], FieldDescriptor attach_function :message_discard_unknown, :upb_Message_DiscardUnknown, [:Message, Descriptor, :int], :bool @@ -170,7 +170,15 @@ module Google message = new mini_table_ptr = Google::Protobuf::FFI.get_mini_table(message.class.descriptor) - status = Google::Protobuf::FFI.decode_message(data, data.bytesize, message.instance_variable_get(:@msg), mini_table_ptr, nil, decoding_options, message.instance_variable_get(:@arena)) + status = Google::Protobuf::FFI.decode_message( + data, + data.bytesize, + message.instance_variable_get(:@msg), + mini_table_ptr, + Google::Protobuf::FFI.get_extension_registry(message.class.descriptor.send(:pool).descriptor_pool), + decoding_options, + message.instance_variable_get(:@arena) + ) raise ParseError.new "Error occurred during parsing" unless status == :Ok message end @@ -293,6 +301,17 @@ module Google include Google::Protobuf::Internal::Convert + def internal_deep_freeze + freeze + self.class.descriptor.each do |field_descriptor| + next if field_descriptor.has_presence? && !Google::Protobuf::FFI.get_message_has(@msg, field_descriptor) + if field_descriptor.map? or field_descriptor.repeated? or field_descriptor.sub_message? + get_field(field_descriptor).send :internal_deep_freeze + end + end + self + end + def self.setup_accessors! @descriptor.each do |field_descriptor| field_name = field_descriptor.name @@ -619,6 +638,7 @@ module Google repeated_field = OBJECT_CACHE.get(array.address) if repeated_field.nil? repeated_field = RepeatedField.send(:construct_for_field, field, @arena, array: array) + repeated_field.send :internal_deep_freeze if frozen? end repeated_field end @@ -631,6 +651,7 @@ module Google map_field = OBJECT_CACHE.get(map.address) if map_field.nil? map_field = Google::Protobuf::Map.send(:construct_for_field, field, @arena, map: map) + map_field.send :internal_deep_freeze if frozen? end map_field end diff --git a/ruby/lib/google/protobuf/ffi/oneof_descriptor.rb b/ruby/lib/google/protobuf/ffi/oneof_descriptor.rb index 00d1d04ea3..00acc995c1 100644 --- a/ruby/lib/google/protobuf/ffi/oneof_descriptor.rb +++ b/ruby/lib/google/protobuf/ffi/oneof_descriptor.rb @@ -22,10 +22,7 @@ module Google # @param value [OneofDescriptor] FieldDescriptor to convert to an FFI native type # @param _ [Object] Unused def to_native(value, _ = nil) - oneof_def_ptr = value.instance_variable_get(:@oneof_def) - warn "Underlying oneof_def was nil!" if oneof_def_ptr.nil? - raise "Underlying oneof_def was null!" if !oneof_def_ptr.nil? and oneof_def_ptr.null? - oneof_def_ptr + value.instance_variable_get(:@oneof_def) || ::FFI::Pointer::NULL end ## @@ -56,6 +53,15 @@ module Google nil end + def options + @options ||= begin + size_ptr = ::FFI::MemoryPointer.new(:size_t, 1) + temporary_arena = Google::Protobuf::FFI.create_arena + buffer = Google::Protobuf::FFI.oneof_options(self, size_ptr, temporary_arena) + Google::Protobuf::OneofOptions.decode(buffer.read_string_length(size_ptr.read(:size_t)).force_encoding("ASCII-8BIT").freeze).send(:internal_deep_freeze) + end + end + private def initialize(oneof_def, descriptor_pool) @@ -72,17 +78,18 @@ module Google class FFI # MessageDef - attach_function :get_oneof_by_name, :upb_MessageDef_FindOneofByNameWithSize, [Descriptor, :string, :size_t], OneofDescriptor - attach_function :get_oneof_by_index, :upb_MessageDef_Oneof, [Descriptor, :int], OneofDescriptor + attach_function :get_oneof_by_name, :upb_MessageDef_FindOneofByNameWithSize, [Descriptor, :string, :size_t], OneofDescriptor + attach_function :get_oneof_by_index, :upb_MessageDef_Oneof, [Descriptor, :int], OneofDescriptor # OneofDescriptor - attach_function :get_oneof_name, :upb_OneofDef_Name, [OneofDescriptor], :string - attach_function :get_oneof_field_count, :upb_OneofDef_FieldCount, [OneofDescriptor], :int - attach_function :get_oneof_field_by_index, :upb_OneofDef_Field, [OneofDescriptor, :int], FieldDescriptor - attach_function :get_oneof_containing_type,:upb_OneofDef_ContainingType,[:pointer], Descriptor + attach_function :get_oneof_name, :upb_OneofDef_Name, [OneofDescriptor], :string + attach_function :get_oneof_field_count, :upb_OneofDef_FieldCount, [OneofDescriptor], :int + attach_function :get_oneof_field_by_index, :upb_OneofDef_Field, [OneofDescriptor, :int], FieldDescriptor + attach_function :get_oneof_containing_type,:upb_OneofDef_ContainingType, [:pointer], Descriptor + attach_function :oneof_options, :OneOfDescriptor_serialized_options, [OneofDescriptor, :pointer, Internal::Arena], :pointer # FieldDescriptor - attach_function :real_containing_oneof, :upb_FieldDef_RealContainingOneof,[FieldDescriptor], OneofDescriptor + attach_function :real_containing_oneof, :upb_FieldDef_RealContainingOneof, [FieldDescriptor], OneofDescriptor end end end diff --git a/ruby/lib/google/protobuf/ffi/repeated_field.rb b/ruby/lib/google/protobuf/ffi/repeated_field.rb index c75ea17284..ccc95ad6f4 100644 --- a/ruby/lib/google/protobuf/ffi/repeated_field.rb +++ b/ruby/lib/google/protobuf/ffi/repeated_field.rb @@ -5,8 +5,6 @@ # license that can be found in the LICENSE file or at # https://developers.google.com/open-source/licenses/bsd -require 'forwardable' - # # This class makes RepeatedField act (almost-) like a Ruby Array. # It has convenience methods that extend the core C or Java based @@ -15,7 +13,7 @@ require 'forwardable' # This is a best-effort to mirror Array behavior. Two comments: # 1) patches always welcome :) # 2) if performance is an issue, feel free to rewrite the method -# in jruby and C. The source code has plenty of examples +# in C. The source code has plenty of examples # # KNOWN ISSUES # - #[]= doesn't allow less used approaches such as `arr[1, 2] = 'fizz'` @@ -35,19 +33,6 @@ module Google end class RepeatedField - extend Forwardable - # NOTE: using delegators rather than method_missing to make the - # relationship explicit instead of implicit - def_delegators :to_ary, - :&, :*, :-, :'<=>', - :assoc, :bsearch, :bsearch_index, :combination, :compact, :count, - :cycle, :dig, :drop, :drop_while, :eql?, :fetch, :find_index, :flatten, - :include?, :index, :inspect, :join, - :pack, :permutation, :product, :pretty_print, :pretty_print_cycle, - :rassoc, :repeated_combination, :repeated_permutation, :reverse, - :rindex, :rotate, :sample, :shuffle, :shelljoin, - :to_s, :transpose, :uniq, :| - include Enumerable ## @@ -262,128 +247,21 @@ module Google push(*other.to_a) end - def first(n=nil) - if n.nil? - return self[0] - elsif n < 0 - raise ArgumentError, "negative array size" - else - return self[0...n] - end - end - - - def last(n=nil) - if n.nil? - return self[-1] - elsif n < 0 - raise ArgumentError, "negative array size" - else - start = [self.size-n, 0].max - return self[start...self.size] - end - end - - - def pop(n=nil) - if n - results = [] - n.times{ results << pop_one } - return results - else - return pop_one - end - end - - - def empty? - self.size == 0 - end - - # array aliases into enumerable - alias_method :each_index, :each_with_index - alias_method :slice, :[] - alias_method :values_at, :select - alias_method :map, :collect - - - class << self - def define_array_wrapper_method(method_name) - define_method(method_name) do |*args, &block| - arr = self.to_a - result = arr.send(method_name, *args) - self.replace(arr) - return result if result - return block ? block.call : result - end - end - private :define_array_wrapper_method - - - def define_array_wrapper_with_result_method(method_name) - define_method(method_name) do |*args, &block| - # result can be an Enumerator, Array, or nil - # Enumerator can sometimes be returned if a block is an optional argument and it is not passed in - # nil usually specifies that no change was made - result = self.to_a.send(method_name, *args, &block) - if result - new_arr = result.to_a - self.replace(new_arr) - if result.is_a?(Enumerator) - # generate a fresh enum; rewinding the exiting one, in Ruby 2.2, will - # reset the enum with the same length, but all the #next calls will - # return nil - result = new_arr.to_enum - # generate a wrapper enum so any changes which occur by a chained - # enum can be captured - ie = ProxyingEnumerator.new(self, result) - result = ie.to_enum - end - end - result - end - end - private :define_array_wrapper_with_result_method - end - - - %w(delete delete_at shift slice! unshift).each do |method_name| - define_array_wrapper_method(method_name) - end + private + include Google::Protobuf::Internal::Convert + attr :name, :arena, :array, :type, :descriptor - %w(collect! compact! delete_if fill flatten! insert reverse! - rotate! select! shuffle! sort! sort_by! uniq!).each do |method_name| - define_array_wrapper_with_result_method(method_name) - end - alias_method :keep_if, :select! - alias_method :map!, :collect! - alias_method :reject!, :delete_if - - - # propagates changes made by user of enumerator back to the original repeated field. - # This only applies in cases where the calling function which created the enumerator, - # such as #sort!, modifies itself rather than a new array, such as #sort - class ProxyingEnumerator < Struct.new(:repeated_field, :external_enumerator) - def each(*args, &block) - results = [] - external_enumerator.each_with_index do |val, i| - result = yield(val) - results << result - #nil means no change occurred from yield; usually occurs when #to_a is called - if result - repeated_field[i] = result if result != val - end + def internal_deep_freeze + freeze + if type == :message + each do |element| + element.send :internal_deep_freeze end - results end + self end - private - include Google::Protobuf::Internal::Convert - - attr :name, :arena, :array, :type, :descriptor - def internal_push(*elements) elements.each do |element| append_msg_val convert_ruby_to_upb(element, arena, type, descriptor) @@ -501,3 +379,5 @@ module Google end end end + +require 'google/protobuf/repeated_field' diff --git a/ruby/lib/google/tasks/ffi.rake b/ruby/lib/google/tasks/ffi.rake index 00e665fee2..c7b2a8e547 100644 --- a/ruby/lib/google/tasks/ffi.rake +++ b/ruby/lib/google/tasks/ffi.rake @@ -1,5 +1,3 @@ -require "ffi-compiler/compile_task" - # # @param task [FFI::Compiler::CompileTask] task to configure def configure_common_compile_task(task) if FileUtils.pwd.include? 'ext' @@ -49,46 +47,56 @@ def with_generated_files end end -desc "Compile Protobuf library for FFI" -namespace "ffi-protobuf" do - with_generated_files do - # Compile Ruby UPB separately in order to limit use of -DUPB_BUILD_API to one - # compilation unit. - desc "Compile UPB library for FFI" - namespace "ffi-upb" do - with_generated_files do - FFI::Compiler::CompileTask.new('ruby-upb') do |c| - configure_common_compile_task c - c.add_define "UPB_BUILD_API" - c.exclude << "/glue.c" - c.exclude << "/shared_message.c" - c.exclude << "/shared_convert.c" - if RbConfig::CONFIG['target_os'] =~ /darwin|linux/ - c.cflags << "-fvisibility=hidden" +begin + require "ffi-compiler/compile_task" + + desc "Compile Protobuf library for FFI" + namespace "ffi-protobuf" do + with_generated_files do + # Compile Ruby UPB separately in order to limit use of -DUPB_BUILD_API to one + # compilation unit. + desc "Compile UPB library for FFI" + namespace "ffi-upb" do + with_generated_files do + FFI::Compiler::CompileTask.new('ruby-upb') do |c| + configure_common_compile_task c + c.add_define "UPB_BUILD_API" + c.exclude << "/glue.c" + c.exclude << "/shared_message.c" + c.exclude << "/shared_convert.c" + if RbConfig::CONFIG['target_os'] =~ /darwin|linux/ + c.cflags << "-fvisibility=hidden" + end end end end - end - FFI::Compiler::CompileTask.new 'protobuf_c_ffi' do |c| - configure_common_compile_task c - # Ruby UPB was already compiled with different flags. - c.exclude << "/range2-neon.c" - c.exclude << "/range2-sse.c" - c.exclude << "/naive.c" - c.exclude << "/ruby-upb.c" - end + FFI::Compiler::CompileTask.new 'protobuf_c_ffi' do |c| + configure_common_compile_task c + # Ruby UPB was already compiled with different flags. + c.exclude << "/range2-neon.c" + c.exclude << "/range2-sse.c" + c.exclude << "/naive.c" + c.exclude << "/ruby-upb.c" + end - # Setup dependencies so that the .o files generated by building ffi-upb are - # available to link here. - # TODO Can this be simplified? Can the single shared library be used - # instead of the object files? - protobuf_c_task = Rake::Task[:default] - protobuf_c_shared_lib_task = Rake::Task[protobuf_c_task.prereqs.last] - ruby_upb_shared_lib_task = Rake::Task[:"ffi-upb:default"].prereqs.first - Rake::Task[ruby_upb_shared_lib_task].prereqs.each do |dependency| - protobuf_c_shared_lib_task.prereqs.prepend dependency + # Setup dependencies so that the .o files generated by building ffi-upb are + # available to link here. + # TODO Can this be simplified? Can the single shared library be used + # instead of the object files? + protobuf_c_task = Rake::Task[:default] + protobuf_c_shared_lib_task = Rake::Task[protobuf_c_task.prereqs.last] + ruby_upb_shared_lib_task = Rake::Task[:"ffi-upb:default"].prereqs.first + Rake::Task[ruby_upb_shared_lib_task].prereqs.each do |dependency| + protobuf_c_shared_lib_task.prereqs.prepend dependency + end + end + end +rescue LoadError + desc "Compile Protobuf library for FFI" + namespace "ffi-protobuf" do + task :default do + warn "Skipping build of FFI; `gem install ffi-compiler` to enable." end end end - diff --git a/ruby/pom.xml b/ruby/pom.xml index 2242464e23..5cd8245c5a 100644 --- a/ruby/pom.xml +++ b/ruby/pom.xml @@ -9,7 +9,7 @@ com.google.protobuf.jruby protobuf-jruby - 3.24.0 + 3.25.0 Protocol Buffer JRuby native extension Protocol Buffers are a way of encoding structured data in an efficient yet @@ -76,7 +76,7 @@ com.google.protobuf protobuf-java-util - 3.24.0 + 3.25.0 org.jruby diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptor.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptor.java index b809253315..aa64d1a5e7 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptor.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptor.java @@ -32,6 +32,7 @@ package com.google.protobuf.jruby; +import com.google.protobuf.CodedInputStream; import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.Descriptors.OneofDescriptor; @@ -158,6 +159,22 @@ public class RubyDescriptor extends RubyObject { return Helpers.nullToNil(oneofDescriptors.get(Utils.symToString(name)), context.nil); } + @JRubyMethod + public IRubyObject options(ThreadContext context) { + RubyDescriptorPool pool = (RubyDescriptorPool) RubyDescriptorPool.generatedPool(null, null); + RubyDescriptor messageOptionsDescriptor = + (RubyDescriptor) + pool.lookup(context, context.runtime.newString("google.protobuf.MessageOptions")); + RubyClass messageOptionsClass = (RubyClass) messageOptionsDescriptor.msgclass(context); + RubyMessage msg = (RubyMessage) messageOptionsClass.newInstance(context, Block.NULL_BLOCK); + return msg.decodeBytes( + context, + msg, + CodedInputStream.newInstance( + descriptor.getOptions().toByteString().toByteArray()), /*freeze*/ + true); + } + protected FieldDescriptor getField(String name) { return descriptor.findFieldByName(name); } diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptorPool.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptorPool.java index d65b412a0a..7c01eb9270 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptorPool.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyDescriptorPool.java @@ -36,7 +36,9 @@ import com.google.protobuf.DescriptorProtos.FileDescriptorProto; import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.DescriptorValidationException; import com.google.protobuf.Descriptors.EnumDescriptor; +import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.Descriptors.FileDescriptor; +import com.google.protobuf.ExtensionRegistry; import com.google.protobuf.InvalidProtocolBufferException; import java.util.ArrayList; import java.util.HashMap; @@ -70,6 +72,7 @@ public class RubyDescriptorPool extends RubyObject { cDescriptorPool.newInstance(runtime.getCurrentContext(), Block.NULL_BLOCK); cDescriptor = (RubyClass) runtime.getClassFromPath("Google::Protobuf::Descriptor"); cEnumDescriptor = (RubyClass) runtime.getClassFromPath("Google::Protobuf::EnumDescriptor"); + cFieldDescriptor = (RubyClass) runtime.getClassFromPath("Google::Protobuf::FieldDescriptor"); } public RubyDescriptorPool(Ruby runtime, RubyClass klazz) { @@ -92,7 +95,7 @@ public class RubyDescriptorPool extends RubyObject { * call-seq: * DescriptorPool.lookup(name) => descriptor * - * Finds a Descriptor or EnumDescriptor by name and returns it, or nil if none + * Finds a Descriptor, EnumDescriptor or FieldDescriptor by name and returns it, or nil if none * exists with the given name. * * This currently lazy loads the ruby descriptor objects as they are requested. @@ -121,7 +124,8 @@ public class RubyDescriptorPool extends RubyObject { public IRubyObject add_serialized_file(ThreadContext context, IRubyObject data) { byte[] bin = data.convertToString().getBytes(); try { - FileDescriptorProto.Builder builder = FileDescriptorProto.newBuilder().mergeFrom(bin); + FileDescriptorProto.Builder builder = + FileDescriptorProto.newBuilder().mergeFrom(bin, registry); registerFileDescriptor(context, builder); } catch (InvalidProtocolBufferException e) { throw RaiseException.from( @@ -150,6 +154,8 @@ public class RubyDescriptorPool extends RubyObject { for (EnumDescriptor ed : fd.getEnumTypes()) registerEnumDescriptor(context, ed, packageName); for (Descriptor message : fd.getMessageTypes()) registerDescriptor(context, message, packageName); + for (FieldDescriptor fieldDescriptor : fd.getExtensions()) + registerExtension(context, fieldDescriptor, packageName); // Mark this as a loaded file fileDescriptors.add(fd); @@ -170,6 +176,24 @@ public class RubyDescriptorPool extends RubyObject { registerEnumDescriptor(context, ed, fullPath); for (Descriptor message : descriptor.getNestedTypes()) registerDescriptor(context, message, fullPath); + for (FieldDescriptor fieldDescriptor : descriptor.getExtensions()) + registerExtension(context, fieldDescriptor, fullPath); + } + + private void registerExtension( + ThreadContext context, FieldDescriptor descriptor, String parentPath) { + if (descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + registry.add(descriptor, descriptor.toProto()); + } else { + registry.add(descriptor); + } + RubyString name = context.runtime.newString(parentPath + descriptor.getName()); + RubyFieldDescriptor des = + (RubyFieldDescriptor) cFieldDescriptor.newInstance(context, Block.NULL_BLOCK); + des.setName(name); + des.setDescriptor(context, descriptor, this); + // For MessageSet extensions, there is the possibility of a name conflict. Prefer the Message. + symtab.putIfAbsent(name, des); } private void registerEnumDescriptor( @@ -188,8 +212,10 @@ public class RubyDescriptorPool extends RubyObject { private static RubyClass cDescriptor; private static RubyClass cEnumDescriptor; + private static RubyClass cFieldDescriptor; private static RubyDescriptorPool descriptorPool; private List fileDescriptors; private Map symtab; + protected static final ExtensionRegistry registry = ExtensionRegistry.newInstance(); } diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java index 24c03cd4d9..7e8247c014 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyEnumDescriptor.java @@ -32,6 +32,7 @@ package com.google.protobuf.jruby; +import com.google.protobuf.CodedInputStream; import com.google.protobuf.DescriptorProtos.EnumDescriptorProto; import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor; @@ -124,6 +125,22 @@ public class RubyEnumDescriptor extends RubyObject { return RubyFileDescriptor.getRubyFileDescriptor(context, descriptor); } + @JRubyMethod + public IRubyObject options(ThreadContext context) { + RubyDescriptorPool pool = (RubyDescriptorPool) RubyDescriptorPool.generatedPool(null, null); + RubyDescriptor enumOptionsDescriptor = + (RubyDescriptor) + pool.lookup(context, context.runtime.newString("google.protobuf.EnumOptions")); + RubyClass enumOptionsClass = (RubyClass) enumOptionsDescriptor.msgclass(context); + RubyMessage msg = (RubyMessage) enumOptionsClass.newInstance(context, Block.NULL_BLOCK); + return msg.decodeBytes( + context, + msg, + CodedInputStream.newInstance( + descriptor.getOptions().toByteString().toByteArray()), /*freeze*/ + true); + } + public boolean isValidValue(ThreadContext context, IRubyObject value) { EnumValueDescriptor enumValue; @@ -198,9 +215,9 @@ public class RubyEnumDescriptor extends RubyObject { // always start with uppercase letters. We tolerate this case by capitalizing // the first character if possible. return new StringBuilder() - .appendCodePoint(Character.toUpperCase(ch)) - .append(name.substring(1)) - .toString(); + .appendCodePoint(Character.toUpperCase(ch)) + .append(name.substring(1)) + .toString(); } } return name; diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyFieldDescriptor.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyFieldDescriptor.java index 50f42cfa70..1d647ea8d9 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyFieldDescriptor.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyFieldDescriptor.java @@ -32,11 +32,13 @@ package com.google.protobuf.jruby; +import com.google.protobuf.CodedInputStream; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.LegacyDescriptorsUtil.LegacyFileDescriptor; import org.jruby.*; import org.jruby.anno.JRubyClass; import org.jruby.anno.JRubyMethod; +import org.jruby.runtime.Block; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; @@ -101,6 +103,10 @@ public class RubyFieldDescriptor extends RubyObject { return this.name; } + protected void setName(IRubyObject name) { + this.name = name; + } + /* * call-seq: * FieldDescriptor.subtype => message_or_enum_descriptor @@ -227,10 +233,25 @@ public class RubyFieldDescriptor extends RubyObject { */ @JRubyMethod(name = "set") public IRubyObject setValue(ThreadContext context, IRubyObject message, IRubyObject value) { - ((RubyMessage) message).setField(context, descriptor, value); + ((RubyMessage) message).setField(context, this, value); return context.nil; } + @JRubyMethod + public IRubyObject options(ThreadContext context) { + RubyDescriptor fieldOptionsDescriptor = + (RubyDescriptor) + pool.lookup(context, context.runtime.newString("google.protobuf.FieldOptions")); + RubyClass fieldOptionsClass = (RubyClass) fieldOptionsDescriptor.msgclass(context); + RubyMessage msg = (RubyMessage) fieldOptionsClass.newInstance(context, Block.NULL_BLOCK); + return msg.decodeBytes( + context, + msg, + CodedInputStream.newInstance( + descriptor.getOptions().toByteString().toByteArray()), /*freeze*/ + true); + } + protected void setDescriptor( ThreadContext context, FieldDescriptor descriptor, RubyDescriptorPool pool) { if (descriptor.isRequired() @@ -246,6 +267,10 @@ public class RubyFieldDescriptor extends RubyObject { this.pool = pool; } + protected FieldDescriptor getDescriptor() { + return descriptor; + } + private void calculateLabel(ThreadContext context) { if (descriptor.isRepeated()) { this.label = context.runtime.newSymbol("repeated"); diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyFileDescriptor.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyFileDescriptor.java index 650480684f..db9580de98 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyFileDescriptor.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyFileDescriptor.java @@ -32,6 +32,7 @@ package com.google.protobuf.jruby; +import com.google.protobuf.CodedInputStream; import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.GenericDescriptor; import com.google.protobuf.LegacyDescriptorsUtil.LegacyFileDescriptor; @@ -106,6 +107,22 @@ public class RubyFileDescriptor extends RubyObject { } } + @JRubyMethod + public IRubyObject options(ThreadContext context) { + RubyDescriptorPool pool = (RubyDescriptorPool) RubyDescriptorPool.generatedPool(null, null); + RubyDescriptor fileOptionsDescriptor = + (RubyDescriptor) + pool.lookup(context, context.runtime.newString("google.protobuf.FileOptions")); + RubyClass fileOptionsClass = (RubyClass) fileOptionsDescriptor.msgclass(context); + RubyMessage msg = (RubyMessage) fileOptionsClass.newInstance(context, Block.NULL_BLOCK); + return msg.decodeBytes( + context, + msg, + CodedInputStream.newInstance( + fileDescriptor.getOptions().toByteString().toByteArray()), /*freeze*/ + true); + } + private static RubyClass cFileDescriptor; private FileDescriptor fileDescriptor; diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java index 8727b13cf7..f3849b1b2a 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMap.java @@ -372,6 +372,16 @@ public class RubyMap extends RubyObject { return RubyHash.newHash(context.runtime, mapForHash, context.nil); } + protected IRubyObject deepFreeze(ThreadContext context) { + setFrozen(true); + if (valueType == FieldDescriptor.Type.MESSAGE) { + for (IRubyObject key : table.keySet()) { + ((RubyMessage) table.get(key)).deepFreeze(context); + } + } + return this; + } + // Used by Google::Protobuf.deep_copy but not exposed directly. protected IRubyObject deepCopy(ThreadContext context) { RubyMap newMap = newThisType(context); diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java index 209f35eeb3..ec57a4bff2 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyMessage.java @@ -42,6 +42,7 @@ import com.google.protobuf.Descriptors.OneofDescriptor; import com.google.protobuf.DynamicMessage; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.LegacyDescriptorsUtil.LegacyFileDescriptor; +import com.google.protobuf.LegacyDescriptorsUtil.LegacyOneofDescriptor; import com.google.protobuf.Message; import com.google.protobuf.UnknownFieldSet; import com.google.protobuf.util.JsonFormat; @@ -628,9 +629,13 @@ public class RubyMessage extends RubyObject { input.setRecursionLimit(((RubyNumeric) recursionLimit).getIntValue()); } } + return decodeBytes(context, ret, input, /*freeze*/ false); + } + public static IRubyObject decodeBytes( + ThreadContext context, RubyMessage ret, CodedInputStream input, boolean freeze) { try { - ret.builder.mergeFrom(input); + ret.builder.mergeFrom(input, RubyDescriptorPool.registry); } catch (Exception e) { throw RaiseException.from( context.runtime, @@ -658,7 +663,9 @@ public class RubyMessage extends RubyObject { } }); } - + if (freeze) { + ret.deepFreeze(context); + } return ret; } @@ -811,6 +818,22 @@ public class RubyMessage extends RubyObject { return ret; } + protected IRubyObject deepFreeze(ThreadContext context) { + setFrozen(true); + for (FieldDescriptor fdef : descriptor.getFields()) { + if (fdef.isMapField()) { + ((RubyMap) fields.get(fdef)).deepFreeze(context); + } else if (fdef.isRepeated()) { + this.getRepeatedField(context, fdef).deepFreeze(context); + } else if (fields.containsKey(fdef)) { + if (fdef.getType() == FieldDescriptor.Type.MESSAGE) { + ((RubyMessage) fields.get(fdef)).deepFreeze(context); + } + } + } + return this; + } + protected DynamicMessage build(ThreadContext context, int depth, int recursionLimit) { if (depth >= recursionLimit) { throw context.runtime.newRuntimeError("Recursion limit exceeded during encoding."); @@ -943,6 +966,12 @@ public class RubyMessage extends RubyObject { return setFieldInternal(context, fieldDescriptor, value); } + protected IRubyObject setField( + ThreadContext context, RubyFieldDescriptor fieldDescriptor, IRubyObject value) { + validateMessageType(context, fieldDescriptor.getDescriptor(), "set"); + return setFieldInternal(context, fieldDescriptor.getDescriptor(), fieldDescriptor, value); + } + private RubyRepeatedField getRepeatedField( ThreadContext context, FieldDescriptor fieldDescriptor) { if (fields.containsKey(fieldDescriptor)) { @@ -1253,6 +1282,14 @@ public class RubyMessage extends RubyObject { private IRubyObject setFieldInternal( ThreadContext context, FieldDescriptor fieldDescriptor, IRubyObject value) { + return setFieldInternal(context, fieldDescriptor, null, value); + } + + private IRubyObject setFieldInternal( + ThreadContext context, + FieldDescriptor fieldDescriptor, + RubyFieldDescriptor rubyFieldDescriptor, + IRubyObject value) { testFrozen("can't modify frozen " + getMetaClass()); if (fieldDescriptor.isMapField()) { @@ -1277,8 +1314,12 @@ public class RubyMessage extends RubyObject { // Determine the typeclass, if any IRubyObject typeClass = context.runtime.getObject(); if (fieldType == FieldDescriptor.Type.MESSAGE) { - typeClass = - ((RubyDescriptor) getDescriptorForField(context, fieldDescriptor)).msgclass(context); + if (rubyFieldDescriptor != null) { + typeClass = ((RubyDescriptor) rubyFieldDescriptor.getSubtype(context)).msgclass(context); + } else { + typeClass = + ((RubyDescriptor) getDescriptorForField(context, fieldDescriptor)).msgclass(context); + } if (value.isNil()) { addValue = false; } @@ -1300,7 +1341,7 @@ public class RubyMessage extends RubyObject { // Keep track of what Oneofs are set if (value.isNil()) { oneofCases.remove(oneofDescriptor); - if (!oneofDescriptor.isSynthetic()) { + if (!LegacyOneofDescriptor.isSynthetic(oneofDescriptor)) { addValue = false; } } else { diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyOneofDescriptor.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyOneofDescriptor.java index 5ade98b7f3..36fe2d0e8a 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyOneofDescriptor.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyOneofDescriptor.java @@ -1,5 +1,6 @@ package com.google.protobuf.jruby; +import com.google.protobuf.CodedInputStream; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.Descriptors.OneofDescriptor; import java.util.ArrayList; @@ -66,6 +67,22 @@ public class RubyOneofDescriptor extends RubyObject { return context.nil; } + @JRubyMethod + public IRubyObject options(ThreadContext context) { + RubyDescriptorPool pool = (RubyDescriptorPool) RubyDescriptorPool.generatedPool(null, null); + RubyDescriptor oneofOptionsDescriptor = + (RubyDescriptor) + pool.lookup(context, context.runtime.newString("google.protobuf.OneofOptions")); + RubyClass oneofOptionsClass = (RubyClass) oneofOptionsDescriptor.msgclass(context); + RubyMessage msg = (RubyMessage) oneofOptionsClass.newInstance(context, Block.NULL_BLOCK); + return msg.decodeBytes( + context, + msg, + CodedInputStream.newInstance( + descriptor.getOptions().toByteString().toByteArray()), /*freeze*/ + true); + } + protected Collection getFields() { return fields; } diff --git a/ruby/src/main/java/com/google/protobuf/jruby/RubyRepeatedField.java b/ruby/src/main/java/com/google/protobuf/jruby/RubyRepeatedField.java index 90ab541518..085dd1cc0f 100644 --- a/ruby/src/main/java/com/google/protobuf/jruby/RubyRepeatedField.java +++ b/ruby/src/main/java/com/google/protobuf/jruby/RubyRepeatedField.java @@ -111,6 +111,7 @@ public class RubyRepeatedField extends RubyObject { */ @JRubyMethod(name = "[]=") public IRubyObject indexSet(ThreadContext context, IRubyObject index, IRubyObject value) { + testFrozen("Can't set index in frozen repeated field"); int arrIndex = normalizeArrayIndex(index); value = Utils.checkType(context, fieldType, name, value, (RubyModule) typeClass); IRubyObject defaultValue = defaultValue(context); @@ -183,6 +184,7 @@ public class RubyRepeatedField extends RubyObject { required = 1, rest = true) public IRubyObject push(ThreadContext context, IRubyObject[] args) { + testFrozen("Can't push frozen repeated field"); for (int i = 0; i < args.length; i++) { IRubyObject val = args[i]; if (fieldType != FieldDescriptor.Type.MESSAGE || !val.isNil()) { @@ -199,6 +201,7 @@ public class RubyRepeatedField extends RubyObject { */ @JRubyMethod(visibility = org.jruby.runtime.Visibility.PRIVATE) public IRubyObject pop_one(ThreadContext context) { + testFrozen("Can't pop frozen repeated field"); IRubyObject ret = this.storage.last(); this.storage.remove(ret); return ret; @@ -212,6 +215,7 @@ public class RubyRepeatedField extends RubyObject { */ @JRubyMethod public IRubyObject replace(ThreadContext context, IRubyObject list) { + testFrozen("Can't replace frozen repeated field"); RubyArray arr = (RubyArray) list; checkArrayElementType(context, arr); this.storage = arr; @@ -226,6 +230,7 @@ public class RubyRepeatedField extends RubyObject { */ @JRubyMethod public IRubyObject clear(ThreadContext context) { + testFrozen("Can't clear frozen repeated field"); this.storage.clear(); return this; } @@ -274,6 +279,7 @@ public class RubyRepeatedField extends RubyObject { */ @JRubyMethod public IRubyObject concat(ThreadContext context, IRubyObject list) { + testFrozen("Can't concat frozen repeated field"); if (list instanceof RubyArray) { checkArrayElementType(context, (RubyArray) list); this.storage.addAll((RubyArray) list); @@ -352,6 +358,16 @@ public class RubyRepeatedField extends RubyObject { return storage.inspect(); } + protected IRubyObject deepFreeze(ThreadContext context) { + setFrozen(true); + if (fieldType == FieldDescriptor.Type.MESSAGE) { + for (int i = 0; i < size(); i++) { + ((RubyMessage) storage.eltInternal(i)).deepFreeze(context); + } + } + return this; + } + // Java API protected IRubyObject get(int index) { return this.storage.eltInternal(index); diff --git a/ruby/tests/basic.rb b/ruby/tests/basic.rb index f35544d343..1e5e7a341d 100755 --- a/ruby/tests/basic.rb +++ b/ruby/tests/basic.rb @@ -695,6 +695,82 @@ module BasicTest msg.map_string_int32_as_value = :boom end end + + def test_file_descriptor_options + file_descriptor = TestMessage.descriptor.file_descriptor + + assert_instance_of Google::Protobuf::FileOptions, file_descriptor.options + assert file_descriptor.options.deprecated + end + + def test_field_descriptor_options + field_descriptor = TestDeprecatedMessage.descriptor.lookup("foo") + + assert_instance_of Google::Protobuf::FieldOptions, field_descriptor.options + assert field_descriptor.options.deprecated + end + + def test_descriptor_options + descriptor = TestDeprecatedMessage.descriptor + + assert_instance_of Google::Protobuf::MessageOptions, descriptor.options + assert descriptor.options.deprecated + end + + def test_enum_descriptor_options + enum_descriptor = TestDeprecatedEnum.descriptor + + assert_instance_of Google::Protobuf::EnumOptions, enum_descriptor.options + assert enum_descriptor.options.deprecated + end + + def test_oneof_descriptor_options + descriptor = TestDeprecatedMessage.descriptor + oneof_descriptor = descriptor.lookup_oneof("test_deprecated_message_oneof") + + assert_instance_of Google::Protobuf::OneofOptions, oneof_descriptor.options + test_top_level_option = Google::Protobuf::DescriptorPool.generated_pool.lookup 'basic_test.test_top_level_option' + assert_instance_of Google::Protobuf::FieldDescriptor, test_top_level_option + assert_equal "Custom option value", test_top_level_option.get(oneof_descriptor.options) + end + + def test_nested_extension + descriptor = TestDeprecatedMessage.descriptor + oneof_descriptor = descriptor.lookup_oneof("test_deprecated_message_oneof") + + assert_instance_of Google::Protobuf::OneofOptions, oneof_descriptor.options + test_nested_option = Google::Protobuf::DescriptorPool.generated_pool.lookup 'basic_test.TestDeprecatedMessage.test_nested_option' + assert_instance_of Google::Protobuf::FieldDescriptor, test_nested_option + assert_equal "Another custom option value", test_nested_option.get(oneof_descriptor.options) + end + + def test_options_deep_freeze + descriptor = TestDeprecatedMessage.descriptor + + assert_raise FrozenError do + descriptor.options.uninterpreted_option.push \ + Google::Protobuf::UninterpretedOption.new + end + end + + def test_message_deep_freeze + message = TestDeprecatedMessage.new + omit(":internal_deep_freeze only exists under FFI") unless message.respond_to? :internal_deep_freeze, true + nested_message_2 = TestMessage2.new + + message.map_string_msg["message"] = TestMessage2.new + message.repeated_msg.push(TestMessage2.new) + + message.send(:internal_deep_freeze) + + assert_raise FrozenError do + message.map_string_msg["message"].foo = "bar" + end + + assert_raise FrozenError do + message.repeated_msg[0].foo = "bar" + end + end end def test_oneof_fields_respond_to? # regression test for issue 9202 diff --git a/ruby/tests/basic_proto2.rb b/ruby/tests/basic_proto2.rb index e9e99e5459..1eefc6ff8d 100755 --- a/ruby/tests/basic_proto2.rb +++ b/ruby/tests/basic_proto2.rb @@ -269,5 +269,57 @@ module BasicTestProto2 assert msg.respond_to? :has_d? refute msg.has_d? end + + def test_extension + message = TestExtensions.new + extension = Google::Protobuf::DescriptorPool.generated_pool.lookup 'basic_test_proto2.optional_int32_extension' + assert_instance_of Google::Protobuf::FieldDescriptor, extension + assert_equal 0, extension.get(message) + extension.set message, 42 + assert_equal 42, extension.get(message) + end + + def test_nested_extension + message = TestExtensions.new + extension = Google::Protobuf::DescriptorPool.generated_pool.lookup 'basic_test_proto2.TestNestedExtension.test' + assert_instance_of Google::Protobuf::FieldDescriptor, extension + assert_equal 'test', extension.get(message) + extension.set message, 'another test' + assert_equal 'another test', extension.get(message) + end + + def test_message_set_extension_json_roundtrip + omit "Java Protobuf JsonFormat does not handle Proto2 extensions" if defined? JRUBY_VERSION and :NATIVE == Google::Protobuf::IMPLEMENTATION + message = TestMessageSet.new + ext1 = Google::Protobuf::DescriptorPool.generated_pool.lookup 'basic_test_proto2.TestMessageSetExtension1.message_set_extension' + assert_instance_of Google::Protobuf::FieldDescriptor, ext1 + ext2 = Google::Protobuf::DescriptorPool.generated_pool.lookup 'basic_test_proto2.TestMessageSetExtension2.message_set_extension' + assert_instance_of Google::Protobuf::FieldDescriptor, ext2 + ext3 = Google::Protobuf::DescriptorPool.generated_pool.lookup 'basic_test_proto2.message_set_extension3' + assert_instance_of Google::Protobuf::FieldDescriptor, ext3 + ext1.set(message, ext1.subtype.msgclass.new(i: 42)) + ext2.set(message, ext2.subtype.msgclass.new(str: 'foo')) + ext3.set(message, ext3.subtype.msgclass.new(text: 'bar')) + message_text = message.to_json + parsed_message = TestMessageSet.decode_json message_text + assert_equal message, parsed_message + end + + + def test_message_set_extension_roundtrip + message = TestMessageSet.new + ext1 = Google::Protobuf::DescriptorPool.generated_pool.lookup 'basic_test_proto2.TestMessageSetExtension1.message_set_extension' + assert_instance_of Google::Protobuf::FieldDescriptor, ext1 + ext2 = Google::Protobuf::DescriptorPool.generated_pool.lookup 'basic_test_proto2.TestMessageSetExtension2.message_set_extension' + assert_instance_of Google::Protobuf::FieldDescriptor, ext2 + ext3 = Google::Protobuf::DescriptorPool.generated_pool.lookup 'basic_test_proto2.message_set_extension3' + assert_instance_of Google::Protobuf::FieldDescriptor, ext3 + ext1.set(message, ext1.subtype.msgclass.new(i: 42)) + ext2.set(message, ext2.subtype.msgclass.new(str: 'foo')) + ext3.set(message, ext3.subtype.msgclass.new(text: 'bar')) + encoded_message = TestMessageSet.encode message + decoded_message = TestMessageSet.decode encoded_message + assert_equal message, decoded_message + end end end diff --git a/ruby/tests/basic_test.proto b/ruby/tests/basic_test.proto index d480d48e54..8feab6ed63 100644 --- a/ruby/tests/basic_test.proto +++ b/ruby/tests/basic_test.proto @@ -2,12 +2,15 @@ syntax = "proto3"; package basic_test; -import "google/protobuf/wrappers.proto"; -import "google/protobuf/timestamp.proto"; +import "google/protobuf/descriptor.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/wrappers.proto"; import "test_import_proto2.proto"; +option deprecated = true; + message Foo { Bar bar = 1; repeated Baz baz = 2; @@ -68,6 +71,31 @@ message TestMessage2 { optional int32 foo = 1; } +extend google.protobuf.OneofOptions { + optional string test_top_level_option = 1000; +} + +message TestDeprecatedMessage { + option deprecated = true; + + extend google.protobuf.OneofOptions { + optional string test_nested_option = 1001; + } + + optional int32 foo = 1 [deprecated = true]; + + oneof test_deprecated_message_oneof { + option (test_top_level_option) = "Custom option value"; + option (test_nested_option) = "Another custom option value"; + + string a = 2; + int32 b = 3; + } + + map map_string_msg = 4; + repeated TestMessage2 repeated_msg = 5; +} + enum TestEnum { Default = 0; A = 1; @@ -76,6 +104,13 @@ enum TestEnum { v0 = 4; } +enum TestDeprecatedEnum { + option deprecated = true; + + DefaultA = 0; + AA = 1 [deprecated = true]; +} + message TestEmbeddedMessageParent { TestEmbeddedMessageChild child_msg = 1; int32 number = 2; @@ -130,8 +165,7 @@ message Outer { map items = 1; } -message Inner { -} +message Inner {} message Wrapper { google.protobuf.DoubleValue double = 1; @@ -213,8 +247,8 @@ message MyStruct { } message WithJsonName { - optional int32 foo_bar = 1 [json_name="jsonFooBar"]; - repeated WithJsonName baz = 2 [json_name="jsonBaz"]; + optional int32 foo_bar = 1 [json_name = "jsonFooBar"]; + repeated WithJsonName baz = 2 [json_name = "jsonBaz"]; } message HelloRequest { diff --git a/ruby/tests/basic_test_proto2.proto b/ruby/tests/basic_test_proto2.proto index ac705ed630..777b4dd776 100644 --- a/ruby/tests/basic_test_proto2.proto +++ b/ruby/tests/basic_test_proto2.proto @@ -2,10 +2,10 @@ syntax = "proto2"; package basic_test_proto2; -import "google/protobuf/wrappers.proto"; -import "google/protobuf/timestamp.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/wrappers.proto"; message Foo { optional Bar bar = 1; @@ -188,3 +188,46 @@ message MyStruct { optional string string = 1; optional google.protobuf.Struct struct = 2; } + +message TestExtensions { + extensions 1 to max; +} + +message TestNestedExtension { + extend TestExtensions { + optional string test = 1002 [default = "test"]; + } +} + +extend TestExtensions { + optional int32 optional_int32_extension = 1; +} + +// A message with message_set_wire_format. +message TestMessageSet { + option message_set_wire_format = true; + + extensions 4 to max; +} + +message TestMessageSetExtension1 { + extend TestMessageSet { + optional TestMessageSetExtension1 message_set_extension = 98418603; + } + optional int32 i = 15; +} + +message TestMessageSetExtension2 { + extend TestMessageSet { + optional TestMessageSetExtension2 message_set_extension = 98418634; + } + optional string str = 25; +} + +message TestMessageSetExtension3 { + optional string text = 35; +} + +extend TestMessageSet { + optional TestMessageSetExtension3 message_set_extension3 = 98418655; +} diff --git a/rust/BUILD b/rust/BUILD index 3e0ca71ed6..bc6a5cc9f4 100644 --- a/rust/BUILD +++ b/rust/BUILD @@ -56,6 +56,7 @@ PROTOBUF_SHARED = [ "shared.rs", "string.rs", "vtable.rs", + "map.rs", ] # The Rust Protobuf runtime using the upb kernel. @@ -67,6 +68,9 @@ rust_library( name = "protobuf_upb", srcs = PROTOBUF_SHARED + ["upb.rs"], crate_root = "shared.rs", + proc_macro_deps = [ + "@crate_index//:paste", + ], rustc_flags = ["--cfg=upb_kernel"], visibility = [ "//src/google/protobuf:__subpackages__", @@ -82,6 +86,9 @@ rust_test( name = "protobuf_upb_test", crate = ":protobuf_upb", rustc_flags = ["--cfg=upb_kernel"], + deps = [ + "@crate_index//:googletest", + ], ) # The Rust Protobuf runtime using the cpp kernel. @@ -107,6 +114,9 @@ rust_test( name = "protobuf_cpp_test", crate = ":protobuf_cpp", rustc_flags = ["--cfg=cpp_kernel"], + deps = [ + "@crate_index//:googletest", + ], ) rust_library( diff --git a/rust/aspects.bzl b/rust/aspects.bzl index 68a590e76a..a91cede87f 100644 --- a/rust/aspects.bzl +++ b/rust/aspects.bzl @@ -323,7 +323,6 @@ def _make_proto_library_aspect(is_upb): ), }, fragments = ["cpp"], - host_fragments = ["cpp"], toolchains = [ "@rules_rust//rust:toolchain_type", "@bazel_tools//tools/cpp:toolchain_type", diff --git a/rust/cpp.rs b/rust/cpp.rs index 7c4998f875..2090a662f9 100644 --- a/rust/cpp.rs +++ b/rust/cpp.rs @@ -7,10 +7,13 @@ // Rust Protobuf runtime using the C++ kernel. -use crate::__internal::{Private, RawArena, RawMessage, RawRepeatedField}; +use crate::ProtoStr; +use crate::__internal::{Private, PtrAndLen, RawArena, RawMap, RawMessage, RawRepeatedField}; +use core::fmt::Debug; use paste::paste; use std::alloc::Layout; use std::cell::UnsafeCell; +use std::convert::identity; use std::fmt; use std::marker::PhantomData; use std::mem::MaybeUninit; @@ -138,7 +141,7 @@ impl fmt::Debug for SerializedData { pub type BytesPresentMutData<'msg> = crate::vtable::RawVTableOptionalMutatorData<'msg, [u8]>; pub type BytesAbsentMutData<'msg> = crate::vtable::RawVTableOptionalMutatorData<'msg, [u8]>; pub type InnerBytesMut<'msg> = crate::vtable::RawVTableMutator<'msg, [u8]>; -pub type InnerPrimitiveMut<'a, T> = crate::vtable::RawVTableMutator<'a, T>; +pub type InnerPrimitiveMut<'msg, T> = crate::vtable::RawVTableMutator<'msg, T>; /// The raw contents of every generated message. #[derive(Debug)] @@ -171,15 +174,23 @@ impl<'msg> MutatorMessageRef<'msg> { MutatorMessageRef { msg: msg.msg, _phantom: PhantomData } } + pub fn from_parent( + _private: Private, + _parent_msg: &'msg mut MessageInner, + message_field_ptr: RawMessage, + ) -> Self { + MutatorMessageRef { msg: message_field_ptr, _phantom: PhantomData } + } + pub fn msg(&self) -> RawMessage { self.msg } } -pub fn copy_bytes_in_arena_if_needed_by_runtime<'a>( - _msg_ref: MutatorMessageRef<'a>, - val: &'a [u8], -) -> &'a [u8] { +pub fn copy_bytes_in_arena_if_needed_by_runtime<'msg>( + _msg_ref: MutatorMessageRef<'msg>, + val: &'msg [u8], +) -> &'msg [u8] { // Nothing to do, the message manages its own string memory for C++. val } @@ -311,9 +322,184 @@ impl<'msg, T: RepeatedScalarOps> RepeatedField<'msg, T> { } } +#[derive(Debug)] +pub struct MapInner<'msg, K: ?Sized, V: ?Sized> { + pub raw: RawMap, + pub _phantom_key: PhantomData<&'msg mut K>, + pub _phantom_value: PhantomData<&'msg mut V>, +} + +impl<'msg, K: ?Sized, V: ?Sized> Copy for MapInner<'msg, K, V> {} +impl<'msg, K: ?Sized, V: ?Sized> Clone for MapInner<'msg, K, V> { + fn clone(&self) -> MapInner<'msg, K, V> { + *self + } +} + +macro_rules! generate_map_with_key_ops_traits { + ($($t:ty, $sized_t:ty;)*) => { + paste! { + $( + pub trait [< MapWith $t:camel KeyOps >] { + type Value<'msg>: Sized; + + fn new_map() -> RawMap; + fn clear(m: RawMap); + fn size(m: RawMap) -> usize; + fn insert(m: RawMap, key: $sized_t, value: Self::Value<'_>) -> bool; + fn get<'msg>(m: RawMap, key: $sized_t) -> Option>; + fn remove(m: RawMap, key: $sized_t) -> bool; + } + + impl<'msg, V: [< MapWith $t:camel KeyOps >] + ?Sized> Default for MapInner<'msg, $t, V> { + fn default() -> Self { + MapInner { + raw: V::new_map(), + _phantom_key: PhantomData, + _phantom_value: PhantomData + } + } + } + + impl<'msg, V: [< MapWith $t:camel KeyOps >] + ?Sized> MapInner<'msg, $t, V> { + pub fn size(&self) -> usize { + V::size(self.raw) + } + + pub fn clear(&mut self) { + V::clear(self.raw) + } + + pub fn get<'a>(&self, key: $sized_t) -> Option> { + V::get(self.raw, key) + } + + pub fn remove(&mut self, key: $sized_t) -> bool { + V::remove(self.raw, key) + } + + pub fn insert(&mut self, key: $sized_t, value: V::Value<'_>) -> bool { + V::insert(self.raw, key, value); + true + } + } + )* + } + } +} + +generate_map_with_key_ops_traits!( + i32, i32; + u32, u32; + i64, i64; + u64, u64; + bool, bool; + ProtoStr, &ProtoStr; +); + +macro_rules! impl_scalar_map_with_key_op_for_scalar_values { + ($key_t:ty, $sized_key_t:ty, $ffi_key_t:ty, $to_ffi_key:expr, $trait:ident for $($t:ty, $sized_t:ty, $ffi_t:ty, $to_ffi_value:expr, $from_ffi_value:expr, $zero_val:literal;)*) => { + paste! { $( + extern "C" { + fn [< __pb_rust_Map_ $key_t _ $t _new >]() -> RawMap; + fn [< __pb_rust_Map_ $key_t _ $t _clear >](m: RawMap); + fn [< __pb_rust_Map_ $key_t _ $t _size >](m: RawMap) -> usize; + fn [< __pb_rust_Map_ $key_t _ $t _insert >](m: RawMap, key: $ffi_key_t, value: $ffi_t); + fn [< __pb_rust_Map_ $key_t _ $t _get >](m: RawMap, key: $ffi_key_t, value: *mut $ffi_t) -> bool; + fn [< __pb_rust_Map_ $key_t _ $t _remove >](m: RawMap, key: $ffi_key_t, value: *mut $ffi_t) -> bool; + } + impl $trait for $t { + type Value<'msg> = $sized_t; + + fn new_map() -> RawMap { + unsafe { [< __pb_rust_Map_ $key_t _ $t _new >]() } + } + + fn clear(m: RawMap) { + unsafe { [< __pb_rust_Map_ $key_t _ $t _clear >](m) } + } + + fn size(m: RawMap) -> usize { + unsafe { [< __pb_rust_Map_ $key_t _ $t _size >](m) } + } + + fn insert(m: RawMap, key: $sized_key_t, value: Self::Value<'_>) -> bool { + let ffi_key = $to_ffi_key(key); + let ffi_value = $to_ffi_value(value); + unsafe { [< __pb_rust_Map_ $key_t _ $t _insert >](m, ffi_key, ffi_value) } + true + } + + fn get<'msg>(m: RawMap, key: $sized_key_t) -> Option> { + let ffi_key = $to_ffi_key(key); + let mut ffi_value = $to_ffi_value($zero_val); + let found = unsafe { [< __pb_rust_Map_ $key_t _ $t _get >](m, ffi_key, &mut ffi_value) }; + if !found { + return None; + } + Some($from_ffi_value(ffi_value)) + } + + fn remove(m: RawMap, key: $sized_key_t) -> bool { + let ffi_key = $to_ffi_key(key); + let mut ffi_value = $to_ffi_value($zero_val); + unsafe { [< __pb_rust_Map_ $key_t _ $t _remove >](m, ffi_key, &mut ffi_value) } + } + } + )* } + } +} + +fn str_to_ptrlen<'msg>(val: impl Into<&'msg ProtoStr>) -> PtrAndLen { + val.into().as_bytes().into() +} + +fn ptrlen_to_str<'msg>(val: PtrAndLen) -> &'msg ProtoStr { + unsafe { ProtoStr::from_utf8_unchecked(val.as_ref()) } +} + +macro_rules! impl_map_with_key_ops_for_scalar_values { + ($($t:ty, $t_sized:ty, $ffi_t:ty, $to_ffi_key:expr;)*) => { + paste! { + $( + impl_scalar_map_with_key_op_for_scalar_values!($t, $t_sized, $ffi_t, $to_ffi_key, [< MapWith $t:camel KeyOps >] for + f32, f32, f32, identity, identity, 0f32; + f64, f64, f64, identity, identity, 0f64; + i32, i32, i32, identity, identity, 0i32; + u32, u32, u32, identity, identity, 0u32; + i64, i64, i64, identity, identity, 0i64; + u64, u64, u64, identity, identity, 0u64; + bool, bool, bool, identity, identity, false; + ProtoStr, &'msg ProtoStr, PtrAndLen, str_to_ptrlen, ptrlen_to_str, ""; + ); + )* + } + } +} + +impl_map_with_key_ops_for_scalar_values!( + i32, i32, i32, identity; + u32, u32, u32, identity; + i64, i64, i64, identity; + u64, u64, u64, identity; + bool, bool, bool, identity; + ProtoStr, &ProtoStr, PtrAndLen, str_to_ptrlen; +); + +#[cfg(test)] +pub(crate) fn new_map_i32_i64() -> MapInner<'static, i32, i64> { + Default::default() +} + +#[cfg(test)] +pub(crate) fn new_map_str_str() -> MapInner<'static, ProtoStr, ProtoStr> { + Default::default() +} + #[cfg(test)] mod tests { use super::*; + use googletest::prelude::*; use std::boxed::Box; // We need to allocate the byte array so SerializedData can own it and @@ -327,30 +513,118 @@ mod tests { #[test] fn test_serialized_data_roundtrip() { let (ptr, len) = allocate_byte_array(b"Hello world"); - let serialized_data = SerializedData { data: NonNull::new(ptr).unwrap(), len: len }; - assert_eq!(&*serialized_data, b"Hello world"); + let serialized_data = SerializedData { data: NonNull::new(ptr).unwrap(), len }; + assert_that!(&*serialized_data, eq(b"Hello world")); } #[test] fn repeated_field() { let mut r = RepeatedField::::new(); - assert_eq!(r.len(), 0); + assert_that!(r.len(), eq(0)); r.push(32); - assert_eq!(r.get(0), Some(32)); + assert_that!(r.get(0), eq(Some(32))); let mut r = RepeatedField::::new(); - assert_eq!(r.len(), 0); + assert_that!(r.len(), eq(0)); r.push(32); - assert_eq!(r.get(0), Some(32)); + assert_that!(r.get(0), eq(Some(32))); let mut r = RepeatedField::::new(); - assert_eq!(r.len(), 0); + assert_that!(r.len(), eq(0)); r.push(0.1234f64); - assert_eq!(r.get(0), Some(0.1234)); + assert_that!(r.get(0), eq(Some(0.1234))); let mut r = RepeatedField::::new(); - assert_eq!(r.len(), 0); + assert_that!(r.len(), eq(0)); r.push(true); - assert_eq!(r.get(0), Some(true)); + assert_that!(r.get(0), eq(Some(true))); + } + + #[test] + fn i32_i32_map() { + let mut map: MapInner<'_, i32, i32> = Default::default(); + assert_that!(map.size(), eq(0)); + + assert_that!(map.insert(1, 2), eq(true)); + assert_that!(map.get(1), eq(Some(2))); + assert_that!(map.get(3), eq(None)); + assert_that!(map.size(), eq(1)); + + assert_that!(map.remove(1), eq(true)); + assert_that!(map.size(), eq(0)); + assert_that!(map.remove(1), eq(false)); + + assert_that!(map.insert(4, 5), eq(true)); + assert_that!(map.insert(6, 7), eq(true)); + map.clear(); + assert_that!(map.size(), eq(0)); + } + + #[test] + fn i64_f64_map() { + let mut map: MapInner<'_, i64, f64> = Default::default(); + assert_that!(map.size(), eq(0)); + + assert_that!(map.insert(1, 2.5), eq(true)); + assert_that!(map.get(1), eq(Some(2.5))); + assert_that!(map.get(3), eq(None)); + assert_that!(map.size(), eq(1)); + + assert_that!(map.remove(1), eq(true)); + assert_that!(map.size(), eq(0)); + assert_that!(map.remove(1), eq(false)); + + assert_that!(map.insert(4, 5.1), eq(true)); + assert_that!(map.insert(6, 7.2), eq(true)); + map.clear(); + assert_that!(map.size(), eq(0)); + } + + #[test] + fn str_str_map() { + let mut map = MapInner::<'_, ProtoStr, ProtoStr>::default(); + assert_that!(map.size(), eq(0)); + + map.insert("fizz".into(), "buzz".into()); + assert_that!(map.size(), eq(1)); + assert_that!(map.remove("fizz".into()), eq(true)); + map.clear(); + assert_that!(map.size(), eq(0)); + } + + #[test] + fn u64_str_map() { + let mut map = MapInner::<'_, u64, ProtoStr>::default(); + assert_that!(map.size(), eq(0)); + + map.insert(1, "fizz".into()); + map.insert(2, "buzz".into()); + assert_that!(map.size(), eq(2)); + assert_that!(map.remove(1), eq(true)); + assert_that!(map.get(1), eq(None)); + map.clear(); + assert_that!(map.size(), eq(0)); + } + + #[test] + fn test_all_maps_can_be_constructed() { + macro_rules! gen_proto_values { + ($key_t:ty, $($value_t:ty),*) => { + $( + let map = MapInner::<'_, $key_t, $value_t>::default(); + assert_that!(map.size(), eq(0)); + )* + } + } + + macro_rules! gen_proto_keys { + ($($key_t:ty),*) => { + $( + gen_proto_values!($key_t, f32, f64, i32, u32, i64, bool, ProtoStr); + )* + } + } + + gen_proto_keys!(i32, u32, i64, u64, bool, ProtoStr); } } diff --git a/rust/cpp_kernel/BUILD b/rust/cpp_kernel/BUILD index d10f9e7db8..e9baa3a467 100644 --- a/rust/cpp_kernel/BUILD +++ b/rust/cpp_kernel/BUILD @@ -12,6 +12,7 @@ cc_library( ], deps = [ ":rust_alloc_for_cpp_api", # buildcleaner: keep + "@com_google_absl//absl/strings:string_view", "//:protobuf_nowkt", ], ) diff --git a/rust/cpp_kernel/cpp_api.cc b/rust/cpp_kernel/cpp_api.cc index 1381611064..05aec1f0ae 100644 --- a/rust/cpp_kernel/cpp_api.cc +++ b/rust/cpp_kernel/cpp_api.cc @@ -1,3 +1,9 @@ +#include "rust/cpp_kernel/cpp_api.h" + +#include +#include + +#include "google/protobuf/map.h" #include "google/protobuf/repeated_field.h" extern "C" { @@ -36,4 +42,76 @@ expose_repeated_field_methods(uint64_t, u64); expose_repeated_field_methods(int64_t, i64); #undef expose_repeated_field_methods + +#define expose_scalar_map_methods(key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, \ + value_ty, rust_value_ty, ffi_value_ty, \ + to_cpp_value, to_ffi_value) \ + google::protobuf::Map* \ + __pb_rust_Map_##rust_key_ty##_##rust_value_ty##_new() { \ + return new google::protobuf::Map(); \ + } \ + void __pb_rust_Map_##rust_key_ty##_##rust_value_ty##_clear( \ + google::protobuf::Map* m) { \ + m->clear(); \ + } \ + size_t __pb_rust_Map_##rust_key_ty##_##rust_value_ty##_size( \ + google::protobuf::Map* m) { \ + return m->size(); \ + } \ + void __pb_rust_Map_##rust_key_ty##_##rust_value_ty##_insert( \ + google::protobuf::Map* m, ffi_key_ty key, ffi_value_ty value) { \ + auto cpp_key = to_cpp_key; \ + auto cpp_value = to_cpp_value; \ + (*m)[cpp_key] = cpp_value; \ + } \ + bool __pb_rust_Map_##rust_key_ty##_##rust_value_ty##_get( \ + google::protobuf::Map* m, ffi_key_ty key, ffi_value_ty* value) { \ + auto cpp_key = to_cpp_key; \ + auto it = m->find(cpp_key); \ + if (it == m->end()) { \ + return false; \ + } \ + auto& cpp_value = it->second; \ + *value = to_ffi_value; \ + return true; \ + } \ + bool __pb_rust_Map_##rust_key_ty##_##rust_value_ty##_remove( \ + google::protobuf::Map* m, ffi_key_ty key, ffi_value_ty* value) { \ + auto cpp_key = to_cpp_key; \ + auto num_removed = m->erase(cpp_key); \ + return num_removed > 0; \ + } + +#define expose_scalar_map_methods_for_key_type(key_ty, rust_key_ty, \ + ffi_key_ty, to_cpp_key) \ + expose_scalar_map_methods(key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, \ + int32_t, i32, int32_t, value, cpp_value); \ + expose_scalar_map_methods(key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, \ + uint32_t, u32, uint32_t, value, cpp_value); \ + expose_scalar_map_methods(key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, \ + float, f32, float, value, cpp_value); \ + expose_scalar_map_methods(key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, \ + double, f64, double, value, cpp_value); \ + expose_scalar_map_methods(key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, bool, \ + bool, bool, value, cpp_value); \ + expose_scalar_map_methods(key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, \ + uint64_t, u64, uint64_t, value, cpp_value); \ + expose_scalar_map_methods(key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, \ + int64_t, i64, int64_t, value, cpp_value); \ + expose_scalar_map_methods( \ + key_ty, rust_key_ty, ffi_key_ty, to_cpp_key, std::string, ProtoStr, \ + google::protobuf::rust_internal::PtrAndLen, std::string(value.ptr, value.len), \ + google::protobuf::rust_internal::PtrAndLen(cpp_value.data(), cpp_value.size())); + +expose_scalar_map_methods_for_key_type(int32_t, i32, int32_t, key); +expose_scalar_map_methods_for_key_type(uint32_t, u32, uint32_t, key); +expose_scalar_map_methods_for_key_type(bool, bool, bool, key); +expose_scalar_map_methods_for_key_type(uint64_t, u64, uint64_t, key); +expose_scalar_map_methods_for_key_type(int64_t, i64, int64_t, key); +expose_scalar_map_methods_for_key_type(std::string, ProtoStr, + google::protobuf::rust_internal::PtrAndLen, + std::string(key.ptr, key.len)); + +#undef expose_scalar_map_methods +#undef expose_map_methods } diff --git a/rust/defs.bzl b/rust/defs.bzl index c542760056..d51829bb83 100644 --- a/rust/defs.bzl +++ b/rust/defs.bzl @@ -18,7 +18,7 @@ visibility([ ]) def rust_proto_library(name, deps, visibility = [], **args): - """Declares all the boilerplate needed to use Rust protobufs conveniently. + """Declares all the boilerplate needed to use Rust protobufs conveniently. Hopefully no user will ever need to read this code. diff --git a/rust/internal.rs b/rust/internal.rs index d7ea96baaf..be9ddb2203 100644 --- a/rust/internal.rs +++ b/rust/internal.rs @@ -62,6 +62,17 @@ mod _opaque_pointees { _data: [u8; 0], _marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>, } + + /// Opaque pointee for [`RawMap`] + /// + /// This type is not meant to be dereferenced in Rust code. + /// It is only meant to provide type safety for raw pointers + /// which are manipulated behind FFI. + #[repr(C)] + pub struct RawMapData { + _data: [u8; 0], + _marker: std::marker::PhantomData<(*mut u8, ::std::marker::PhantomPinned)>, + } } /// A raw pointer to the underlying message for this runtime. @@ -73,6 +84,9 @@ pub type RawArena = NonNull<_opaque_pointees::RawArenaData>; /// A raw pointer to the underlying repeated field container for this runtime. pub type RawRepeatedField = NonNull<_opaque_pointees::RawRepeatedFieldData>; +/// A raw pointer to the underlying arena for this runtime. +pub type RawMap = NonNull<_opaque_pointees::RawMapData>; + /// Represents an ABI-stable version of `NonNull<[u8]>`/`string_view` (a /// borrowed slice of bytes) for FFI use only. /// diff --git a/rust/macros.rs b/rust/macros.rs index 3109eff06a..4f8334933e 100644 --- a/rust/macros.rs +++ b/rust/macros.rs @@ -19,11 +19,11 @@ /// ``` macro_rules! impl_forwarding_settable_value { ($proxied:ty, $self:ident => $self_forwarding_expr:expr) => { - fn set_on( + fn set_on<'b>( $self, _private: $crate::__internal::Private, - mutator: $crate::Mut<'_, $proxied>, - ) { + mutator: $crate::Mut<'b, $proxied>, + ) where $proxied: 'b { ($self_forwarding_expr).set_on(Private, mutator) } diff --git a/rust/map.rs b/rust/map.rs new file mode 100644 index 0000000000..795c107571 --- /dev/null +++ b/rust/map.rs @@ -0,0 +1,290 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google LLC. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +use crate::{ + Mut, MutProxy, ProtoStr, Proxied, SettableValue, View, ViewProxy, + __internal::Private, + __runtime::{ + MapInner, MapWithBoolKeyOps, MapWithI32KeyOps, MapWithI64KeyOps, MapWithProtoStrKeyOps, + MapWithU32KeyOps, MapWithU64KeyOps, + }, +}; +use paste::paste; +use std::marker::PhantomData; + +#[repr(transparent)] +pub struct MapView<'msg, K: ?Sized, V: ?Sized> { + inner: MapInner<'msg, K, V>, +} + +impl<'msg, K: ?Sized, V: ?Sized> MapView<'msg, K, V> { + pub fn from_inner(_private: Private, inner: MapInner<'msg, K, V>) -> Self { + Self { inner } + } +} + +impl<'msg, K: ?Sized, V: ?Sized> Copy for MapView<'msg, K, V> {} +impl<'msg, K: ?Sized, V: ?Sized> Clone for MapView<'msg, K, V> { + fn clone(&self) -> Self { + *self + } +} + +unsafe impl<'msg, K: ?Sized, V: ?Sized> Sync for MapView<'msg, K, V> {} +unsafe impl<'msg, K: ?Sized, V: ?Sized> Send for MapView<'msg, K, V> {} + +impl<'msg, K: ?Sized, V: ?Sized> std::fmt::Debug for MapView<'msg, K, V> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("MapView") + .field(&std::any::type_name::()) + .field(&std::any::type_name::()) + .finish() + } +} + +#[repr(transparent)] +pub struct MapMut<'msg, K: ?Sized, V: ?Sized> { + inner: MapInner<'msg, K, V>, +} + +impl<'msg, K: ?Sized, V: ?Sized> MapMut<'msg, K, V> { + pub fn from_inner(_private: Private, inner: MapInner<'msg, K, V>) -> Self { + Self { inner } + } +} + +unsafe impl<'msg, K: ?Sized, V: ?Sized> Sync for MapMut<'msg, K, V> {} + +impl<'msg, K: ?Sized, V: ?Sized> std::fmt::Debug for MapMut<'msg, K, V> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("MapMut") + .field(&std::any::type_name::()) + .field(&std::any::type_name::()) + .finish() + } +} + +impl<'msg, K: ?Sized, V: ?Sized> std::ops::Deref for MapMut<'msg, K, V> { + type Target = MapView<'msg, K, V>; + fn deref(&self) -> &Self::Target { + // SAFETY: + // - `Map{View,Mut}<'msg, T>` are both `#[repr(transparent)]` over + // `MapInner<'msg, T>`. + // - `MapInner` is a type alias for `NonNull`. + unsafe { &*(self as *const Self as *const MapView<'msg, K, V>) } + } +} + +// This is a ZST type so we can implement `Proxied`. Users will work with +// `MapView` (`View<'_, Map>>) and `MapMut` (Mut<'_, Map>). +pub struct Map(PhantomData, PhantomData); + +macro_rules! impl_proxied_for_map_keys { + ($(key_type $t:ty;)*) => { + paste! { $( + impl] + Proxied + ?Sized> Proxied for Map<$t, V>{ + type View<'msg> = MapView<'msg, $t, V> where V: 'msg; + type Mut<'msg> = MapMut<'msg, $t, V> where V: 'msg; + } + + impl<'msg, V: [< MapWith $t:camel KeyOps >] + Proxied + ?Sized + 'msg> SettableValue> for MapView<'msg, $t, V> { + fn set_on<'b>(self, _private: Private, mut mutator: Mut<'b, Map<$t, V>>) + where + Map<$t, V>: 'b { + mutator.copy_from(self); + } + } + + impl<'msg, V: [< MapWith $t:camel KeyOps >] + Proxied + ?Sized + 'msg> ViewProxy<'msg> for MapView<'msg, $t, V> { + type Proxied = Map<$t, V>; + + fn as_view(&self) -> View<'_, Self::Proxied> { + *self + } + + fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied> + where 'msg: 'shorter, + { + MapView { inner: self.inner } + } + } + + impl<'msg, V: [< MapWith $t:camel KeyOps >] + Proxied + ?Sized + 'msg> ViewProxy<'msg> for MapMut<'msg, $t, V> { + type Proxied = Map<$t, V>; + + fn as_view(&self) -> View<'_, Self::Proxied> { + **self + } + + fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied> + where 'msg: 'shorter, + { + *self.into_mut::<'shorter>() + } + } + + impl<'msg, V: [< MapWith $t:camel KeyOps >] + Proxied + ?Sized + 'msg> MutProxy<'msg> for MapMut<'msg, $t, V> { + fn as_mut(&mut self) -> Mut<'_, Self::Proxied> { + MapMut { inner: self.inner } + } + + fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied> + where 'msg: 'shorter, + { + MapMut { inner: self.inner } + } + } + )* } + } +} + +impl_proxied_for_map_keys!( + key_type i32; + key_type u32; + key_type i64; + key_type u64; + key_type bool; + key_type ProtoStr; +); + +macro_rules! impl_scalar_map_keys { + ($(key_type $t:ty;)*) => { + paste! { $( + impl<'msg, V: [< MapWith $t:camel KeyOps >] + Proxied + ?Sized + 'msg> MapView<'msg, $t, V> { + pub fn get<'b>(&self, key: $t) -> Option> { + self.inner.get(key) + } + + pub fn len(&self) -> usize { + self.inner.size() + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + } + + impl<'msg, V: [< MapWith $t:camel KeyOps >] + Proxied + ?Sized + 'msg> MapMut<'msg, $t, V> { + pub fn insert(&mut self, key: $t, value: V::Value<'_>) -> bool { + self.inner.insert(key, value) + } + + pub fn remove<'b>(&mut self, key: $t) -> bool { + self.inner.remove(key) + } + + pub fn clear(&mut self) { + self.inner.clear() + } + + pub fn copy_from(&mut self, _src: MapView<'_, $t, V>) { + todo!("implement b/28530933"); + } + } + )* } + }; +} + +impl_scalar_map_keys!( + key_type i32; + key_type u32; + key_type i64; + key_type u64; + key_type bool; +); + +impl<'msg, V: MapWithProtoStrKeyOps + Proxied + ?Sized + 'msg> MapView<'msg, ProtoStr, V> { + pub fn get(&self, key: impl Into<&'msg ProtoStr>) -> Option> { + self.inner.get(key.into()) + } + + pub fn len(&self) -> usize { + self.inner.size() + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } +} + +impl<'msg, V: MapWithProtoStrKeyOps + Proxied + ?Sized + 'msg> MapMut<'msg, ProtoStr, V> { + pub fn insert(&mut self, key: impl Into<&'msg ProtoStr>, value: V::Value<'_>) -> bool { + self.inner.insert(key.into(), value) + } + + pub fn remove(&mut self, key: impl Into<&'msg ProtoStr>) -> bool { + self.inner.remove(key.into()) + } + + pub fn clear(&mut self) { + self.inner.clear() + } + + pub fn copy_from(&mut self, _src: MapView<'_, ProtoStr, V>) { + todo!("implement b/28530933"); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::__runtime::{new_map_i32_i64, new_map_str_str}; + use googletest::prelude::*; + + #[test] + fn test_proxied_scalar() { + let mut map_mut = MapMut::from_inner(Private, new_map_i32_i64()); + map_mut.insert(1, 2); + let map_view_1 = map_mut.as_view(); + assert_that!(map_view_1.len(), eq(1)); + assert_that!(map_view_1.get(1), eq(Some(2))); + + map_mut.insert(3, 4); + + let map_view_2 = map_mut.into_view(); + assert_that!(map_view_2.len(), eq(2)); + assert_that!(map_view_2.get(3), eq(Some(4))); + + { + let map_view_3 = map_view_2.as_view(); + assert_that!(map_view_3.is_empty(), eq(false)); + } + + let map_view_4 = map_view_2.into_view(); + assert_that!(map_view_4.is_empty(), eq(false)); + } + + #[test] + fn test_proxied_str() { + let mut map_mut = MapMut::from_inner(Private, new_map_str_str()); + map_mut.insert("a", "b".into()); + + let map_view_1 = map_mut.as_view(); + assert_that!(map_view_1.len(), eq(1)); + assert_that!(map_view_1.get("a").unwrap(), eq("b")); + + map_mut.insert("c", "d".into()); + + let map_view_2 = map_mut.into_view(); + assert_that!(map_view_2.len(), eq(2)); + assert_that!(map_view_2.get("c").unwrap(), eq("d")); + + { + let map_view_3 = map_view_2.as_view(); + assert_that!(map_view_3.is_empty(), eq(false)); + } + + let map_view_4 = map_view_2.into_view(); + assert_that!(map_view_4.is_empty(), eq(false)); + } + + #[test] + fn test_dbg() { + let map_view = MapView::from_inner(Private, new_map_i32_i64()); + assert_that!(format!("{:?}", map_view), eq("MapView(\"i32\", \"i64\")")); + } +} diff --git a/rust/optional.rs b/rust/optional.rs index ec99653203..0268c61bfd 100644 --- a/rust/optional.rs +++ b/rust/optional.rs @@ -83,7 +83,7 @@ impl From> for Option { /// A mutable view into the value of an optional field, which may be set or /// unset. -pub type FieldEntry<'a, T> = Optional, AbsentField<'a, T>>; +pub type FieldEntry<'msg, T> = Optional, AbsentField<'msg, T>>; /// Methods for `_mut()` accessors of optional types. /// @@ -285,11 +285,11 @@ where /// A field mutator capable of setting that is statically known to point to a /// non-set field. -pub struct AbsentField<'a, T> +pub struct AbsentField<'msg, T> where - T: ProxiedWithPresence + ?Sized + 'a, + T: ProxiedWithPresence + ?Sized + 'msg, { - pub(crate) inner: T::AbsentMutData<'a>, + pub(crate) inner: T::AbsentMutData<'msg>, } impl<'msg, T: ProxiedWithPresence + ?Sized + 'msg> Debug for AbsentField<'msg, T> { @@ -432,10 +432,10 @@ mod tests { } } - fn make_field_entry<'a>( - msg: &'a mut MyMessage, - vtable: &'a ProxyVtable, - ) -> FieldEntry<'a, VtableProxied> { + fn make_field_entry<'msg>( + msg: &'msg mut MyMessage, + vtable: &'msg ProxyVtable, + ) -> FieldEntry<'msg, VtableProxied> { if (vtable.has)(&*msg) { Optional::Set(PresentField::from_inner(Private, VtableProxiedMut { msg, vtable })) } else { @@ -494,8 +494,8 @@ mod tests { struct VtableProxied; impl Proxied for VtableProxied { - type View<'a> = VtableProxiedView; - type Mut<'a> = VtableProxiedMut<'a>; + type View<'msg> = VtableProxiedView; + type Mut<'msg> = VtableProxiedMut<'msg>; } impl ProxiedWithPresence for VtableProxied { @@ -503,19 +503,19 @@ mod tests { // `Mut` in layout. Other types/runtimes could require otherwise, e.g. `Mut` // could be defined to only have get/set functions in its vtable, and not // has/clear. - type PresentMutData<'a> = VtableProxiedMut<'a>; - type AbsentMutData<'a> = VtableProxiedMut<'a>; + type PresentMutData<'msg> = VtableProxiedMut<'msg>; + type AbsentMutData<'msg> = VtableProxiedMut<'msg>; - fn clear_present_field<'a>( - present_mutator: Self::PresentMutData<'a>, - ) -> Self::AbsentMutData<'a> { + fn clear_present_field<'msg>( + present_mutator: Self::PresentMutData<'msg>, + ) -> Self::AbsentMutData<'msg> { (present_mutator.vtable.clear)(&mut *present_mutator.msg); present_mutator } - fn set_absent_to_default<'a>( - absent_mutator: Self::AbsentMutData<'a>, - ) -> Self::PresentMutData<'a> { + fn set_absent_to_default<'msg>( + absent_mutator: Self::AbsentMutData<'msg>, + ) -> Self::PresentMutData<'msg> { SettableValue::::set_on_absent( absent_mutator.as_view().val(), Private, @@ -539,28 +539,28 @@ mod tests { } } - impl<'a> ViewProxy<'a> for VtableProxiedView { + impl<'msg> ViewProxy<'msg> for VtableProxiedView { type Proxied = VtableProxied; - fn as_view(&self) -> View<'a, VtableProxied> { + fn as_view(&self) -> View<'msg, VtableProxied> { *self } fn into_view<'shorter>(self) -> View<'shorter, VtableProxied> where - 'a: 'shorter, + 'msg: 'shorter, { self } } #[derive(Debug)] - struct VtableProxiedMut<'a> { - msg: &'a mut MyMessage, - vtable: &'a ProxyVtable, + struct VtableProxiedMut<'msg> { + msg: &'msg mut MyMessage, + vtable: &'msg ProxyVtable, } - impl<'a> ViewProxy<'a> for VtableProxiedMut<'a> { + impl<'msg> ViewProxy<'msg> for VtableProxiedMut<'msg> { type Proxied = VtableProxied; fn as_view(&self) -> View<'_, VtableProxied> { @@ -569,49 +569,55 @@ mod tests { fn into_view<'shorter>(self) -> View<'shorter, VtableProxied> where - 'a: 'shorter, + 'msg: 'shorter, { VtableProxiedView::read(self.msg, self.vtable) } } - impl<'a> MutProxy<'a> for VtableProxiedMut<'a> { + impl<'msg> MutProxy<'msg> for VtableProxiedMut<'msg> { fn as_mut(&mut self) -> Mut<'_, VtableProxied> { VtableProxiedMut { msg: self.msg, vtable: self.vtable } } fn into_mut<'shorter>(self) -> Mut<'shorter, VtableProxied> where - 'a: 'shorter, + 'msg: 'shorter, { self } } impl SettableValue for View<'_, VtableProxied> { - fn set_on(self, _private: Private, mutator: Mut) { + fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, VtableProxied>) + where + VtableProxied: 'msg, + { SettableValue::::set_on(self.val(), Private, mutator) } - fn set_on_absent<'a>( + fn set_on_absent<'msg>( self, _private: Private, - absent_mutator: ::AbsentMutData<'a>, - ) -> ::PresentMutData<'a> { + absent_mutator: ::AbsentMutData<'msg>, + ) -> ::PresentMutData<'msg> { SettableValue::::set_on_absent(self.val(), Private, absent_mutator) } } impl SettableValue for i32 { - fn set_on(self, _private: Private, mutator: Mut) { + fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, VtableProxied>) + where + VtableProxied: 'msg, + { (mutator.vtable.set)(mutator.msg, self) } - fn set_on_absent<'a>( + fn set_on_absent<'msg>( self, _private: Private, - absent_mutator: ::AbsentMutData<'a>, - ) -> ::PresentMutData<'a> { + absent_mutator: ::AbsentMutData<'msg>, + ) -> ::PresentMutData<'msg> { (absent_mutator.vtable.set)(absent_mutator.msg, self); absent_mutator } @@ -619,109 +625,125 @@ mod tests { #[test] fn test_field_entry() { + use googletest::prelude::*; let mut m1 = MyMessage::default(); let mut m2 = MyMessage::default(); let mut m1_a = m1.a_mut(); - assert!(matches!(m1_a, Optional::Unset(_))); - assert_eq!(m1_a.as_view().val(), 0); + assert_that!(m1_a, matches_pattern!(Optional::Unset(_))); + + assert_that!(m1_a.as_view().val(), eq(0)); - assert_eq!(m2.b().val(), 5); + assert_that!(m2.b().val(), eq(5)); let mut m2_b = m2.b_mut(); - assert!(m2_b.is_unset()); - assert_eq!(m2_b.as_view().val(), 5); + assert_that!(m2_b.is_unset(), eq(true)); + assert_that!(m2_b.as_view().val(), eq(5)); m2_b.set(10); - assert!(m2_b.is_set()); - assert!(matches!(m2_b, Optional::Set(_))); - assert_eq!(m2_b.as_view().val(), 10); + assert_that!(m2_b.is_set(), eq(true)); + assert_that!(m2_b, matches_pattern!(Optional::Set(_))); + assert_that!(m2_b.as_view().val(), eq(10)); - assert_eq!(m1_a.or_default().as_view().val(), 0); - assert_eq!(m1.a_opt(), Optional::Set(VtableProxiedView { val: 0 })); + assert_that!(m1_a.or_default().as_view().val(), eq(0)); + assert_that!(m1.a_opt(), eq(Optional::Set(VtableProxiedView { val: 0 }))); m1.a_mut().clear(); - assert_eq!(m1.a().val(), 0); - assert_eq!(m1.b().val(), 5); - assert_eq!(m2.a().val(), 0); - assert_eq!(m2.b().val(), 10); + assert_that!(m1.a().val(), eq(0)); + assert_that!(m1.b().val(), eq(5)); + assert_that!(m2.a().val(), eq(0)); + assert_that!(m2.b().val(), eq(10)); } #[test] fn test_or_set() { + use googletest::prelude::*; let mut m1 = MyMessage::default(); let mut m2 = MyMessage::default(); - assert_eq!(m1.a_mut().or_set(10).get().val(), 10); - assert_eq!(m1.a_opt(), Optional::Set(VtableProxiedView { val: 10 })); - assert_eq!(m1.a_mut().or_set(20).get().val(), 10); - assert_eq!(m1.a_opt(), Optional::Set(VtableProxiedView { val: 10 })); + assert_that!(m1.a_mut().or_set(10).get().val(), eq(10)); + assert_that!(m1.a_opt(), eq(Optional::Set(VtableProxiedView { val: 10 }))); + assert_that!(m1.a_mut().or_set(20).get().val(), eq(10)); + assert_that!(m1.a_opt(), eq(Optional::Set(VtableProxiedView { val: 10 }))); - assert_eq!(m2.a_mut().or_set_with(|| m1.a().val() + m1.b().val()).get().val(), 15); - assert_eq!(m2.a_opt(), Optional::Set(VtableProxiedView { val: 15 })); - assert_eq!(m2.a_mut().or_set_with(|| None::.unwrap()).get().val(), 15); - assert_eq!(m2.a_opt(), Optional::Set(VtableProxiedView { val: 15 })); + assert_that!(m2.a_mut().or_set_with(|| m1.a().val() + m1.b().val()).get().val(), eq(15)); + assert_that!(m2.a_opt(), eq(Optional::Set(VtableProxiedView { val: 15 }))); + assert_that!(m2.a_mut().or_set_with(|| None::.unwrap()).get().val(), eq(15)); + assert_that!(m2.a_opt(), eq(Optional::Set(VtableProxiedView { val: 15 }))); } #[test] fn test_into_optional_view() { + use googletest::prelude::*; let mut m1 = MyMessage::default(); - assert_eq!(m1.a_mut().into_optional_view(), Optional::Unset(VtableProxiedView { val: 0 })); + assert_that!( + m1.a_mut().into_optional_view(), + eq(Optional::Unset(VtableProxiedView { val: 0 })) + ); m1.a_mut().set(10); - assert_eq!(m1.a_mut().into_optional_view(), Optional::Set(VtableProxiedView { val: 10 })); - assert_eq!(m1.b_mut().into_optional_view(), Optional::Unset(VtableProxiedView { val: 5 })); + assert_that!( + m1.a_mut().into_optional_view(), + eq(Optional::Set(VtableProxiedView { val: 10 })) + ); + assert_that!( + m1.b_mut().into_optional_view(), + eq(Optional::Unset(VtableProxiedView { val: 5 })) + ); } #[test] fn test_try_into_mut() { + use googletest::prelude::*; let mut m1 = MyMessage::default(); - assert!(m1.a_mut().try_into_mut().is_none()); + assert_that!(m1.a_mut().try_into_mut().is_none(), eq(true)); m1.a_mut().set(10); let mut a_mut = m1.a_mut().try_into_mut().expect("field to be set"); a_mut.set(20); - assert_eq!(m1.a().val(), 20); + assert_that!(m1.a().val(), eq(20)); } #[test] fn test_present_field() { + use googletest::prelude::*; let mut m = MyMessage::default(); m.a_mut().set(10); match m.a_mut() { Optional::Set(mut present) => { - assert_eq!(present.as_view().val(), 10); + assert_that!(present.as_view().val(), eq(10)); present.set(20); - assert_eq!(present.as_view().val(), 20); + assert_that!(present.as_view().val(), eq(20)); present.into_mut().set(30); } Optional::Unset(_) => unreachable!(), } - assert_eq!(m.a_opt(), Optional::Set(VtableProxiedView { val: 30 })); + assert_that!(m.a_opt(), eq(Optional::Set(VtableProxiedView { val: 30 }))); m.b_mut().set(20); match m.b_mut() { Optional::Set(present) => present.clear(), Optional::Unset(_) => unreachable!(), }; - assert_eq!(m.b_opt(), Optional::Unset(VtableProxiedView { val: 5 })); + assert_that!(m.b_opt(), eq(Optional::Unset(VtableProxiedView { val: 5 }))); } #[test] fn test_absent_field() { + use googletest::prelude::*; let mut m = MyMessage::default(); match m.a_mut() { Optional::Set(_) => unreachable!(), Optional::Unset(absent) => { - assert_eq!(absent.as_view().val(), 0); + assert_that!(absent.as_view().val(), eq(0)); absent.set(20); } } - assert_eq!(m.a_opt(), Optional::Set(VtableProxiedView { val: 20 })); + assert_that!(m.a_opt(), eq(Optional::Set(VtableProxiedView { val: 20 }))); match m.b_mut() { Optional::Set(_) => unreachable!(), Optional::Unset(absent) => { - assert_eq!(absent.as_view().val(), 5); + assert_that!(absent.as_view().val(), eq(5)); absent.set_default(); } } - assert_eq!(m.b_opt(), Optional::Set(VtableProxiedView { val: 5 })); + assert_that!(m.b_opt(), eq(Optional::Set(VtableProxiedView { val: 5 }))); } } diff --git a/rust/primitive.rs b/rust/primitive.rs index dd2fec18d4..bf4d63268b 100644 --- a/rust/primitive.rs +++ b/rust/primitive.rs @@ -7,7 +7,6 @@ use crate::__internal::Private; use crate::__runtime::InnerPrimitiveMut; -use crate::repeated::RepeatedMut; use crate::vtable::{ PrimitiveOptionalMutVTable, PrimitiveVTable, ProxiedWithRawOptionalVTable, ProxiedWithRawVTable, RawVTableOptionalMutatorData, @@ -15,41 +14,28 @@ use crate::vtable::{ use crate::{Mut, MutProxy, Proxied, ProxiedWithPresence, SettableValue, View, ViewProxy}; #[derive(Debug)] -pub struct SingularPrimitiveMut<'a, T: ProxiedWithRawVTable> { - inner: InnerPrimitiveMut<'a, T>, +pub struct PrimitiveMut<'msg, T: ProxiedWithRawVTable> { + inner: InnerPrimitiveMut<'msg, T>, } -#[derive(Debug)] -pub enum PrimitiveMut<'a, T: ProxiedWithRawVTable> { - Singular(SingularPrimitiveMut<'a, T>), - Repeated(RepeatedMut<'a, T>, usize), -} - -impl<'a, T: ProxiedWithRawVTable> PrimitiveMut<'a, T> { - #[doc(hidden)] - pub fn from_singular(_private: Private, inner: InnerPrimitiveMut<'a, T>) -> Self { - PrimitiveMut::Singular(SingularPrimitiveMut::from_inner(_private, inner)) - } -} - -impl<'a, T: ProxiedWithRawVTable> SingularPrimitiveMut<'a, T> { +impl<'msg, T: ProxiedWithRawVTable> PrimitiveMut<'msg, T> { #[doc(hidden)] - pub fn from_inner(_private: Private, inner: InnerPrimitiveMut<'a, T>) -> Self { + pub fn from_inner(_private: Private, inner: InnerPrimitiveMut<'msg, T>) -> Self { Self { inner } } } -unsafe impl<'a, T: ProxiedWithRawVTable> Sync for SingularPrimitiveMut<'a, T> {} +unsafe impl<'msg, T: ProxiedWithRawVTable> Sync for PrimitiveMut<'msg, T> {} macro_rules! impl_singular_primitives { ($($t:ty),*) => { $( impl Proxied for $t { - type View<'a> = $t; - type Mut<'a> = PrimitiveMut<'a, $t>; + type View<'msg> = $t; + type Mut<'msg> = PrimitiveMut<'msg, $t>; } - impl<'a> ViewProxy<'a> for $t { + impl<'msg> ViewProxy<'msg> for $t { type Proxied = $t; fn as_view(&self) -> View<'_, Self::Proxied> { @@ -61,30 +47,17 @@ macro_rules! impl_singular_primitives { } } - impl<'a> PrimitiveMut<'a, $t> { + impl<'msg> PrimitiveMut<'msg, $t> { pub fn get(&self) -> View<'_, $t> { - match self { - PrimitiveMut::Singular(s) => { - s.get() - } - PrimitiveMut::Repeated(r, i) => { - r.get().get(*i).unwrap() - } - } + self.inner.get() } pub fn set(&mut self, val: impl SettableValue<$t>) { val.set_on(Private, self.as_mut()); } - - pub fn clear(&mut self) { - // The default value for a boolean field is false and 0 for numerical types. It - // matches the Rust default values for corresponding types. Let's use this fact. - SettableValue::<$t>::set_on(<$t>::default(), Private, MutProxy::as_mut(self)); - } } - impl<'a> ViewProxy<'a> for PrimitiveMut<'a, $t> { + impl<'msg> ViewProxy<'msg> for PrimitiveMut<'msg, $t> { type Proxied = $t; fn as_view(&self) -> View<'_, Self::Proxied> { @@ -96,44 +69,22 @@ macro_rules! impl_singular_primitives { } } - impl<'a> MutProxy<'a> for PrimitiveMut<'a, $t> { + impl<'msg> MutProxy<'msg> for PrimitiveMut<'msg, $t> { fn as_mut(&mut self) -> Mut<'_, Self::Proxied> { - match self { - PrimitiveMut::Singular(s) => { - PrimitiveMut::Singular(s.as_mut()) - } - PrimitiveMut::Repeated(r, i) => { - PrimitiveMut::Repeated(r.as_mut(), *i) - } - } + PrimitiveMut { inner: self.inner } } fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied> - where 'a: 'shorter, + where 'msg: 'shorter, { self } } impl SettableValue<$t> for $t { - fn set_on(self, _private: Private, mutator: Mut<'_, $t>) { - match mutator { - PrimitiveMut::Singular(s) => { - unsafe { (s.inner).set(self) }; - } - PrimitiveMut::Repeated(mut r, i) => { - r.set(i, self); - } - } - } - } - - impl<'a> SingularPrimitiveMut<'a, $t> { - pub fn get(&self) -> $t { - self.inner.get() - } - pub fn as_mut(&mut self) -> SingularPrimitiveMut<'_, $t> { - SingularPrimitiveMut::from_inner(Private, self.inner) + fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, $t>) where $t: 'msg { + // SAFETY: the raw mutator is valid for `'msg` as enforced by `Mut` + unsafe { mutator.inner.set(self) } } } @@ -148,13 +99,13 @@ macro_rules! impl_singular_primitives { } fn make_mut(_private: Private, inner: InnerPrimitiveMut<'_, Self>) -> Mut<'_, Self> { - PrimitiveMut::Singular(SingularPrimitiveMut::from_inner(Private, inner)) + PrimitiveMut::from_inner(Private, inner) } } impl ProxiedWithPresence for $t { - type PresentMutData<'a> = RawVTableOptionalMutatorData<'a, $t>; - type AbsentMutData<'a> = RawVTableOptionalMutatorData<'a, $t>; + type PresentMutData<'msg> = RawVTableOptionalMutatorData<'msg, $t>; + type AbsentMutData<'msg> = RawVTableOptionalMutatorData<'msg, $t>; fn clear_present_field( present_mutator: Self::PresentMutData<'_>, diff --git a/rust/proxied.rs b/rust/proxied.rs index 437ba9948d..44bb3e18a0 100644 --- a/rust/proxied.rs +++ b/rust/proxied.rs @@ -55,47 +55,47 @@ use std::marker::{Send, Sync}; /// /// All Protobuf field types implement `Proxied`. pub trait Proxied { - /// The proxy type that provides shared access to a `T`, like a `&'a T`. + /// The proxy type that provides shared access to a `T`, like a `&'msg T`. /// /// Most code should use the type alias [`View`]. - type View<'a>: ViewProxy<'a, Proxied = Self> + Copy + Send + SettableValue + type View<'msg>: ViewProxy<'msg, Proxied = Self> + Copy + Send + SettableValue where - Self: 'a; + Self: 'msg; /// The proxy type that provides exclusive mutable access to a `T`, like a - /// `&'a mut T`. + /// `&'msg mut T`. /// /// Most code should use the type alias [`Mut`]. - type Mut<'a>: MutProxy<'a, Proxied = Self> + type Mut<'msg>: MutProxy<'msg, Proxied = Self> where - Self: 'a; + Self: 'msg; } -/// A proxy type that provides shared access to a `T`, like a `&'a T`. +/// A proxy type that provides shared access to a `T`, like a `&'msg T`. /// /// This is more concise than fully spelling the associated type. #[allow(dead_code)] -pub type View<'a, T> = ::View<'a>; +pub type View<'msg, T> = ::View<'msg>; /// A proxy type that provides exclusive mutable access to a `T`, like a -/// `&'a mut T`. +/// `&'msg mut T`. /// /// This is more concise than fully spelling the associated type. #[allow(dead_code)] -pub type Mut<'a, T> = ::Mut<'a>; +pub type Mut<'msg, T> = ::Mut<'msg>; /// Declares conversion operations common to all views. /// /// This trait is intentionally made non-object-safe to prevent a potential /// future incompatible change. -pub trait ViewProxy<'a>: 'a + Sized + Sync + Unpin + Sized + Debug { - type Proxied: 'a + Proxied + ?Sized; +pub trait ViewProxy<'msg>: 'msg + Sized + Sync + Unpin + Sized + Debug { + type Proxied: 'msg + Proxied + ?Sized; /// Converts a borrow into a `View` with the lifetime of that borrow. /// /// In non-generic code we don't need to use `as_view` because the proxy - /// types are covariant over `'a`. However, generic code conservatively - /// treats `'a` as [invariant], therefore we need to call + /// types are covariant over `'msg`. However, generic code conservatively + /// treats `'msg` as [invariant], therefore we need to call /// `as_view` to explicitly perform the operation that in concrete code /// coercion would perform implicitly. /// @@ -115,8 +115,8 @@ pub trait ViewProxy<'a>: 'a + Sized + Sync + Unpin + Sized + Debug { /// Converts into a `View` with a potentially shorter lifetime. /// /// In non-generic code we don't need to use `into_view` because the proxy - /// types are covariant over `'a`. However, generic code conservatively - /// treats `'a` as [invariant], therefore we need to call + /// types are covariant over `'msg`. However, generic code conservatively + /// treats `'msg` as [invariant], therefore we need to call /// `into_view` to explicitly perform the operation that in concrete /// code coercion would perform implicitly. /// @@ -139,14 +139,14 @@ pub trait ViewProxy<'a>: 'a + Sized + Sync + Unpin + Sized + Debug { /// [invariant]: https://doc.rust-lang.org/nomicon/subtyping.html#variance fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied> where - 'a: 'shorter; + 'msg: 'shorter; } /// Declares operations common to all mutators. /// /// This trait is intentionally made non-object-safe to prevent a potential /// future incompatible change. -pub trait MutProxy<'a>: ViewProxy<'a> { +pub trait MutProxy<'msg>: ViewProxy<'msg> { /// Gets an immutable view of this field. This is shorthand for `as_view`. /// /// This provides a shorter lifetime than `into_view` but can also be called @@ -181,8 +181,8 @@ pub trait MutProxy<'a>: ViewProxy<'a> { /// Converts into a `Mut` with a potentially shorter lifetime. /// /// In non-generic code we don't need to use `into_mut` because the proxy - /// types are covariant over `'a`. However, generic code conservatively - /// treats `'a` as [invariant], therefore we need to call + /// types are covariant over `'msg`. However, generic code conservatively + /// treats `'msg` as [invariant], therefore we need to call /// `into_mut` to explicitly perform the operation that in concrete code /// coercion would perform implicitly. /// @@ -202,7 +202,7 @@ pub trait MutProxy<'a>: ViewProxy<'a> { /// [invariant]: https://doc.rust-lang.org/nomicon/subtyping.html#variance fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied> where - 'a: 'shorter; + 'msg: 'shorter; } /// `Proxied` types that can be optionally set or unset. @@ -211,25 +211,21 @@ pub trait MutProxy<'a>: ViewProxy<'a> { /// types don't. pub trait ProxiedWithPresence: Proxied { /// The data necessary to store a present field mutator proxying `Self`. - /// This is the contents of `PresentField<'a, Self>`. - type PresentMutData<'a>: MutProxy<'a, Proxied = Self>; + /// This is the contents of `PresentField<'msg, Self>`. + type PresentMutData<'msg>: MutProxy<'msg, Proxied = Self>; /// The data necessary to store an absent field mutator proxying `Self`. - /// This is the contents of `AbsentField<'a, Self>`. - type AbsentMutData<'a>: ViewProxy<'a, Proxied = Self>; + /// This is the contents of `AbsentField<'msg, Self>`. + type AbsentMutData<'msg>: ViewProxy<'msg, Proxied = Self>; /// Clears a present field. - fn clear_present_field<'a>( - present_mutator: Self::PresentMutData<'a>, - ) -> Self::AbsentMutData<'a>; + fn clear_present_field(present_mutator: Self::PresentMutData<'_>) -> Self::AbsentMutData<'_>; /// Sets an absent field to its default value. /// /// This can be more efficient than setting with a default value, e.g. /// a default submessage could share resources with the parent message. - fn set_absent_to_default<'a>( - absent_mutator: Self::AbsentMutData<'a>, - ) -> Self::PresentMutData<'a>; + fn set_absent_to_default(absent_mutator: Self::AbsentMutData<'_>) -> Self::PresentMutData<'_>; } /// Values that can be used to set a field of `T`. @@ -239,16 +235,18 @@ where { /// Consumes `self` to set the given mutator to its value. #[doc(hidden)] - fn set_on(self, _private: Private, mutator: Mut<'_, T>); + fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, T>) + where + T: 'msg; /// Consumes `self` and `absent_mutator` to set the given empty field to /// a value. #[doc(hidden)] - fn set_on_absent<'a>( + fn set_on_absent( self, _private: Private, - absent_mutator: T::AbsentMutData<'a>, - ) -> T::PresentMutData<'a> + absent_mutator: T::AbsentMutData<'_>, + ) -> T::PresentMutData<'_> where T: ProxiedWithPresence, { @@ -289,13 +287,13 @@ mod tests { } impl Proxied for MyProxied { - type View<'a> = MyProxiedView<'a>; - type Mut<'a> = MyProxiedMut<'a>; + type View<'msg> = MyProxiedView<'msg>; + type Mut<'msg> = MyProxiedMut<'msg>; } #[derive(Debug, Clone, Copy)] - struct MyProxiedView<'a> { - my_proxied_ref: &'a MyProxied, + struct MyProxiedView<'msg> { + my_proxied_ref: &'msg MyProxied, } impl MyProxiedView<'_> { @@ -304,27 +302,27 @@ mod tests { } } - impl<'a> ViewProxy<'a> for MyProxiedView<'a> { + impl<'msg> ViewProxy<'msg> for MyProxiedView<'msg> { type Proxied = MyProxied; - fn as_view(&self) -> View<'a, MyProxied> { + fn as_view(&self) -> View<'msg, MyProxied> { *self } fn into_view<'shorter>(self) -> View<'shorter, MyProxied> where - 'a: 'shorter, + 'msg: 'shorter, { self } } #[derive(Debug)] - struct MyProxiedMut<'a> { - my_proxied_ref: &'a mut MyProxied, + struct MyProxiedMut<'msg> { + my_proxied_ref: &'msg mut MyProxied, } - impl<'a> ViewProxy<'a> for MyProxiedMut<'a> { + impl<'msg> ViewProxy<'msg> for MyProxiedMut<'msg> { type Proxied = MyProxied; fn as_view(&self) -> View<'_, MyProxied> { @@ -332,45 +330,57 @@ mod tests { } fn into_view<'shorter>(self) -> View<'shorter, MyProxied> where - 'a: 'shorter, + 'msg: 'shorter, { MyProxiedView { my_proxied_ref: self.my_proxied_ref } } } - impl<'a> MutProxy<'a> for MyProxiedMut<'a> { + impl<'msg> MutProxy<'msg> for MyProxiedMut<'msg> { fn as_mut(&mut self) -> Mut<'_, MyProxied> { MyProxiedMut { my_proxied_ref: self.my_proxied_ref } } fn into_mut<'shorter>(self) -> Mut<'shorter, MyProxied> where - 'a: 'shorter, + 'msg: 'shorter, { self } } impl SettableValue for MyProxiedView<'_> { - fn set_on(self, _private: Private, mutator: Mut) { + fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, MyProxied>) + where + MyProxied: 'msg, + { mutator.my_proxied_ref.val = self.my_proxied_ref.val.clone(); } } impl SettableValue for String { - fn set_on(self, _private: Private, mutator: Mut) { + fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, MyProxied>) + where + MyProxied: 'msg, + { mutator.my_proxied_ref.val = self; } } impl SettableValue for &'_ str { - fn set_on(self, _private: Private, mutator: Mut) { + fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, MyProxied>) + where + MyProxied: 'msg, + { mutator.my_proxied_ref.val.replace_range(.., self); } } impl SettableValue for Cow<'_, str> { - fn set_on(self, _private: Private, mutator: Mut) { + fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, MyProxied>) + where + MyProxied: 'msg, + { match self { Cow::Owned(x) => >::set_on(x, Private, mutator), Cow::Borrowed(x) => <&str as SettableValue>::set_on(x, Private, mutator), @@ -399,7 +409,7 @@ mod tests { assert_eq!(my_proxied.val, "Hello indeed"); } - fn reborrow_mut_into_view<'a>(x: Mut<'a, MyProxied>) -> View<'a, MyProxied> { + fn reborrow_mut_into_view<'msg>(x: Mut<'msg, MyProxied>) -> View<'msg, MyProxied> { // x.as_view() fails to compile with: // `ERROR: attempt to return function-local borrowed content` x.into_view() // OK: we return the same lifetime as we got in. @@ -411,7 +421,7 @@ mod tests { reborrow_mut_into_view(my_proxied.as_mut()); } - fn require_unified_lifetimes<'a>(_x: Mut<'a, MyProxied>, _y: View<'a, MyProxied>) {} + fn require_unified_lifetimes<'msg>(_x: Mut<'msg, MyProxied>, _y: View<'msg, MyProxied>) {} #[test] fn test_require_unified_lifetimes() { diff --git a/rust/repeated.rs b/rust/repeated.rs index 1abb7152ba..af0f513408 100644 --- a/rust/repeated.rs +++ b/rust/repeated.rs @@ -15,27 +15,26 @@ use crate::{ Mut, MutProxy, Proxied, SettableValue, View, ViewProxy, __internal::{Private, RawRepeatedField}, __runtime::{RepeatedField, RepeatedFieldInner}, - primitive::PrimitiveMut, vtable::ProxiedWithRawVTable, }; #[derive(Clone, Copy)] -pub struct RepeatedFieldRef<'a> { +pub struct RepeatedFieldRef<'msg> { pub repeated_field: RawRepeatedField, - pub _phantom: PhantomData<&'a mut ()>, + pub _phantom: PhantomData<&'msg mut ()>, } -unsafe impl<'a> Send for RepeatedFieldRef<'a> {} -unsafe impl<'a> Sync for RepeatedFieldRef<'a> {} +unsafe impl<'msg> Send for RepeatedFieldRef<'msg> {} +unsafe impl<'msg> Sync for RepeatedFieldRef<'msg> {} #[derive(Clone, Copy)] #[repr(transparent)] -pub struct RepeatedView<'a, T: ?Sized> { - inner: RepeatedField<'a, T>, +pub struct RepeatedView<'msg, T: ?Sized> { + inner: RepeatedField<'msg, T>, } -unsafe impl<'a, T: ProxiedWithRawVTable> Sync for RepeatedView<'a, T> {} -unsafe impl<'a, T: ProxiedWithRawVTable> Send for RepeatedView<'a, T> {} +unsafe impl<'msg, T: ProxiedWithRawVTable> Sync for RepeatedView<'msg, T> {} +unsafe impl<'msg, T: ProxiedWithRawVTable> Send for RepeatedView<'msg, T> {} impl<'msg, T: ?Sized> RepeatedView<'msg, T> { pub fn from_inner(_private: Private, inner: RepeatedFieldInner<'msg>) -> Self { @@ -43,12 +42,12 @@ impl<'msg, T: ?Sized> RepeatedView<'msg, T> { } } -pub struct RepeatedFieldIter<'a, T> { - inner: RepeatedField<'a, T>, +pub struct RepeatedFieldIter<'msg, T> { + inner: RepeatedField<'msg, T>, current_index: usize, } -impl<'a, T> std::fmt::Debug for RepeatedView<'a, T> { +impl<'msg, T> std::fmt::Debug for RepeatedView<'msg, T> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple("RepeatedView").finish() } @@ -56,11 +55,11 @@ impl<'a, T> std::fmt::Debug for RepeatedView<'a, T> { #[repr(transparent)] #[derive(Debug)] -pub struct RepeatedMut<'a, T: ?Sized> { - inner: RepeatedField<'a, T>, +pub struct RepeatedMut<'msg, T: ?Sized> { + inner: RepeatedField<'msg, T>, } -unsafe impl<'a, T: ProxiedWithRawVTable> Sync for RepeatedMut<'a, T> {} +unsafe impl<'msg, T: ProxiedWithRawVTable> Sync for RepeatedMut<'msg, T> {} impl<'msg, T: ?Sized> RepeatedMut<'msg, T> { pub fn from_inner(_private: Private, inner: RepeatedFieldInner<'msg>) -> Self { @@ -71,33 +70,28 @@ impl<'msg, T: ?Sized> RepeatedMut<'msg, T> { } } -impl<'a, T> std::ops::Deref for RepeatedMut<'a, T> { - type Target = RepeatedView<'a, T>; +impl<'msg, T> std::ops::Deref for RepeatedMut<'msg, T> { + type Target = RepeatedView<'msg, T>; fn deref(&self) -> &Self::Target { // SAFETY: - // - `Repeated{View,Mut}<'a, T>` are both `#[repr(transparent)]` over - // `RepeatedField<'a, T>`. + // - `Repeated{View,Mut}<'msg, T>` are both `#[repr(transparent)]` over + // `RepeatedField<'msg, T>`. // - `RepeatedField` is a type alias for `NonNull`. - unsafe { &*(self as *const Self as *const RepeatedView<'a, T>) } + unsafe { &*(self as *const Self as *const RepeatedView<'msg, T>) } } } -pub struct RepeatedFieldIterMut<'a, T> { - inner: RepeatedMut<'a, T>, - current_index: usize, -} - pub struct Repeated(PhantomData); macro_rules! impl_repeated_primitives { ($($t:ty),*) => { $( impl Proxied for Repeated<$t> { - type View<'a> = RepeatedView<'a, $t>; - type Mut<'a> = RepeatedMut<'a, $t>; + type View<'msg> = RepeatedView<'msg, $t>; + type Mut<'msg> = RepeatedMut<'msg, $t>; } - impl<'a> ViewProxy<'a> for RepeatedView<'a, $t> { + impl<'msg> ViewProxy<'msg> for RepeatedView<'msg, $t> { type Proxied = Repeated<$t>; fn as_view(&self) -> View<'_, Self::Proxied> { @@ -105,13 +99,13 @@ macro_rules! impl_repeated_primitives { } fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied> - where 'a: 'shorter, + where 'msg: 'shorter, { RepeatedView { inner: self.inner } } } - impl<'a> ViewProxy<'a> for RepeatedMut<'a, $t> { + impl<'msg> ViewProxy<'msg> for RepeatedMut<'msg, $t> { type Proxied = Repeated<$t>; fn as_view(&self) -> View<'_, Self::Proxied> { @@ -119,31 +113,33 @@ macro_rules! impl_repeated_primitives { } fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied> - where 'a: 'shorter, + where 'msg: 'shorter, { *self.into_mut::<'shorter>() } } - impl<'a> MutProxy<'a> for RepeatedMut<'a, $t> { + impl<'msg> MutProxy<'msg> for RepeatedMut<'msg, $t> { fn as_mut(&mut self) -> Mut<'_, Self::Proxied> { RepeatedMut { inner: self.inner } } fn into_mut<'shorter>(self) -> Mut<'shorter, Self::Proxied> - where 'a: 'shorter, + where 'msg: 'shorter, { RepeatedMut { inner: self.inner } } } - impl <'a> SettableValue> for RepeatedView<'a, $t> { - fn set_on(self, _private: Private, mut mutator: Mut<'_, Repeated<$t>>) { + impl <'msg> SettableValue> for RepeatedView<'msg, $t> { + fn set_on<'b> (self, _private: Private, mut mutator: Mut<'b, Repeated<$t>>) + where + Repeated<$t>: 'b { mutator.copy_from(self); } } - impl<'a> RepeatedView<'a, $t> { + impl<'msg> RepeatedView<'msg, $t> { pub fn len(&self) -> usize { self.inner.len() } @@ -158,31 +154,22 @@ macro_rules! impl_repeated_primitives { } } - impl<'a> RepeatedMut<'a, $t> { + impl<'msg> RepeatedMut<'msg, $t> { pub fn push(&mut self, val: $t) { self.inner.push(val) } pub fn set(&mut self, index: usize, val: $t) { self.inner.set(index, val) } - pub fn get_mut(&mut self, index: usize) -> Option> { - if index >= self.len() { - return None; - } - Some(PrimitiveMut::Repeated(self.as_mut(), index)) - } pub fn iter(&self) -> RepeatedFieldIter<'_, $t> { self.as_view().into_iter() } - pub fn iter_mut(&mut self) -> RepeatedFieldIterMut<'_, $t> { - self.as_mut().into_iter() - } pub fn copy_from(&mut self, src: RepeatedView<'_, $t>) { self.inner.copy_from(&src.inner); } } - impl<'a> std::iter::Iterator for RepeatedFieldIter<'a, $t> { + impl<'msg> std::iter::Iterator for RepeatedFieldIter<'msg, $t> { type Item = $t; fn next(&mut self) -> Option { let val = self.inner.get(self.current_index); @@ -193,39 +180,13 @@ macro_rules! impl_repeated_primitives { } } - impl<'a> std::iter::IntoIterator for RepeatedView<'a, $t> { + impl<'msg> std::iter::IntoIterator for RepeatedView<'msg, $t> { type Item = $t; - type IntoIter = RepeatedFieldIter<'a, $t>; + type IntoIter = RepeatedFieldIter<'msg, $t>; fn into_iter(self) -> Self::IntoIter { RepeatedFieldIter { inner: self.inner, current_index: 0 } } } - - impl <'a> std::iter::Iterator for RepeatedFieldIterMut<'a, $t> { - type Item = Mut<'a, $t>; - fn next(&mut self) -> Option { - if self.current_index >= self.inner.len() { - return None; - } - let elem = PrimitiveMut::Repeated( - // While this appears to allow mutable aliasing - // (multiple `Self::Item`s can co-exist), each `Item` - // only references a specific unique index. - RepeatedMut{ inner: self.inner.inner }, - self.current_index, - ); - self.current_index += 1; - Some(elem) - } - } - - impl<'a> std::iter::IntoIterator for RepeatedMut<'a, $t> { - type Item = Mut<'a, $t>; - type IntoIter = RepeatedFieldIterMut<'a, $t>; - fn into_iter(self) -> Self::IntoIter { - RepeatedFieldIterMut { inner: self, current_index: 0 } - } - } )* } } diff --git a/rust/shared.rs b/rust/shared.rs index 7c3a3d163d..f94f987989 100644 --- a/rust/shared.rs +++ b/rust/shared.rs @@ -17,8 +17,9 @@ use std::fmt; /// These are the items protobuf users can access directly. #[doc(hidden)] pub mod __public { + pub use crate::map::{Map, MapMut, MapView}; pub use crate::optional::{AbsentField, FieldEntry, Optional, PresentField}; - pub use crate::primitive::{PrimitiveMut, SingularPrimitiveMut}; + pub use crate::primitive::PrimitiveMut; pub use crate::proxied::{ Mut, MutProxy, Proxied, ProxiedWithPresence, SettableValue, View, ViewProxy, }; @@ -44,6 +45,7 @@ pub mod __runtime; pub mod __runtime; mod macros; +mod map; mod optional; mod primitive; mod proxied; diff --git a/rust/string.rs b/rust/string.rs index 401dfc3c34..dfaa51918f 100644 --- a/rust/string.rs +++ b/rust/string.rs @@ -128,15 +128,11 @@ impl ProxiedWithPresence for [u8] { type PresentMutData<'msg> = BytesPresentMutData<'msg>; type AbsentMutData<'msg> = BytesAbsentMutData<'msg>; - fn clear_present_field<'a>( - present_mutator: Self::PresentMutData<'a>, - ) -> Self::AbsentMutData<'a> { + fn clear_present_field(present_mutator: Self::PresentMutData<'_>) -> Self::AbsentMutData<'_> { present_mutator.clear() } - fn set_absent_to_default<'a>( - absent_mutator: Self::AbsentMutData<'a>, - ) -> Self::PresentMutData<'a> { + fn set_absent_to_default(absent_mutator: Self::AbsentMutData<'_>) -> Self::PresentMutData<'_> { absent_mutator.set_absent_to_default() } } @@ -185,7 +181,10 @@ impl<'msg> MutProxy<'msg> for BytesMut<'msg> { } impl SettableValue<[u8]> for &'_ [u8] { - fn set_on(self, _private: Private, mutator: BytesMut<'_>) { + fn set_on<'msg>(self, _private: Private, mutator: Mut<'msg, [u8]>) + where + [u8]: 'msg, + { // SAFETY: this is a `bytes` field with no restriction on UTF-8. unsafe { mutator.inner.set(self) } } @@ -695,7 +694,10 @@ impl<'msg> MutProxy<'msg> for ProtoStrMut<'msg> { } impl SettableValue for &'_ ProtoStr { - fn set_on(self, _private: Private, mutator: ProtoStrMut<'_>) { + fn set_on<'b>(self, _private: Private, mutator: Mut<'b, ProtoStr>) + where + ProtoStr: 'b, + { // SAFETY: A `ProtoStr` has the same UTF-8 validity requirement as the runtime. unsafe { mutator.bytes.inner.set(self.as_bytes()) } } diff --git a/rust/test/BUILD b/rust/test/BUILD index 94167810fd..decb41a187 100644 --- a/rust/test/BUILD +++ b/rust/test/BUILD @@ -1,10 +1,10 @@ -load("@rules_cc//cc:defs.bzl", "cc_proto_library") load( "//rust:defs.bzl", "rust_cc_proto_library", "rust_proto_library", "rust_upb_proto_library", ) +load("@rules_cc//cc:defs.bzl", "cc_proto_library") UNITTEST_PROTO_TARGET = "//src/google/protobuf:test_protos" UNITTEST_CC_PROTO_TARGET = "//src/google/protobuf:cc_test_protos" @@ -49,7 +49,7 @@ rust_proto_library( name = "unittest_proto3_rust_proto", testonly = True, visibility = [ - "//rust/test/shared:__subpackages__", + "//visibility:private", # Only private by automation, not intent. Owner may accept CLs adding visibility. See go/scheuklappen#explicit-private. ], deps = [ UNITTEST_PROTO3_TARGET, @@ -59,20 +59,14 @@ rust_proto_library( rust_cc_proto_library( name = "unittest_proto3_cc_rust_proto", testonly = True, - visibility = [ - "//rust/test/cpp:__subpackages__", - "//rust/test/shared:__subpackages__", - ], + visibility = ["//rust/test/shared:__subpackages__"], deps = [UNITTEST_PROTO3_CC_TARGET], ) rust_upb_proto_library( name = "unittest_proto3_upb_rust_proto", testonly = True, - visibility = [ - "//rust/test/cpp:__subpackages__", - "//rust/test/shared:__subpackages__", - ], + visibility = ["//rust/test/shared:__subpackages__"], deps = [UNITTEST_PROTO3_TARGET], ) @@ -80,7 +74,7 @@ rust_proto_library( name = "unittest_proto3_optional_rust_proto", testonly = True, visibility = [ - "//rust/test/shared:__subpackages__", + "//visibility:private", # Only private by automation, not intent. Owner may accept CLs adding visibility. See go/scheuklappen#explicit-private. ], deps = [ UNITTEST_PROTO3_OPTIONAL_TARGET, @@ -90,20 +84,14 @@ rust_proto_library( rust_cc_proto_library( name = "unittest_proto3_optional_cc_rust_proto", testonly = True, - visibility = [ - "//rust/test/cpp:__subpackages__", - "//rust/test/shared:__subpackages__", - ], + visibility = ["//rust/test/shared:__subpackages__"], deps = [UNITTEST_PROTO3_OPTIONAL_CC_TARGET], ) rust_upb_proto_library( name = "unittest_proto3_optional_upb_rust_proto", testonly = True, - visibility = [ - "//rust/test/cpp:__subpackages__", - "//rust/test/shared:__subpackages__", - ], + visibility = ["//rust/test/shared:__subpackages__"], deps = [UNITTEST_PROTO3_OPTIONAL_TARGET], ) @@ -186,6 +174,32 @@ rust_upb_proto_library( deps = [":dots_in_package_proto"], ) +proto_library( + name = "edition2023_proto", + testonly = True, + srcs = ["edition2023.proto"], +) + +cc_proto_library( + name = "edition2023_cc_proto", + testonly = True, + deps = [":edition2023_proto"], +) + +rust_cc_proto_library( + name = "edition2023_cc_rust_proto", + testonly = True, + visibility = ["//rust/test/shared:__subpackages__"], + deps = [":edition2023_cc_proto"], +) + +rust_upb_proto_library( + name = "edition2023_upb_rust_proto", + testonly = True, + visibility = ["//rust/test/shared:__subpackages__"], + deps = [":edition2023_proto"], +) + proto_library( name = "no_package_import_proto", testonly = True, @@ -250,20 +264,14 @@ cc_proto_library( rust_cc_proto_library( name = "package_cc_rust_proto", testonly = True, - visibility = [ - "//rust/test/cpp:__subpackages__", - "//rust/test/shared:__subpackages__", - ], + visibility = ["//rust/test/shared:__subpackages__"], deps = [":package_cc_proto"], ) rust_upb_proto_library( name = "package_upb_rust_proto", testonly = True, - visibility = [ - "//rust/test/shared:__subpackages__", - "//rust/test/upb:__subpackages__", - ], + visibility = ["//rust/test/shared:__subpackages__"], deps = [":package_proto"], ) @@ -282,20 +290,14 @@ cc_proto_library( rust_cc_proto_library( name = "reserved_cc_rust_proto", testonly = True, - visibility = [ - "//rust/test/cpp:__subpackages__", - "//rust/test/shared:__subpackages__", - ], + visibility = ["//rust/test/shared:__subpackages__"], deps = [":reserved_cc_proto"], ) rust_upb_proto_library( name = "reserved_upb_rust_proto", testonly = True, - visibility = [ - "//rust/test/shared:__subpackages__", - "//rust/test/upb:__subpackages__", - ], + visibility = ["//rust/test/shared:__subpackages__"], deps = [":reserved_proto"], ) @@ -330,3 +332,27 @@ rust_upb_proto_library( ], deps = [":nested_proto"], ) + +cc_proto_library( + name = "map_unittest_cc_proto", + testonly = True, + deps = ["//src/google/protobuf:map_unittest_proto"], +) + +rust_cc_proto_library( + name = "map_unittest_cc_rust_proto", + testonly = True, + visibility = [ + "//rust/test/shared:__subpackages__", + ], + deps = [":map_unittest_cc_proto"], +) + +rust_upb_proto_library( + name = "map_unittest_upb_rust_proto", + testonly = True, + visibility = [ + "//rust/test/shared:__subpackages__", + ], + deps = ["//src/google/protobuf:map_unittest_proto"], +) diff --git a/rust/test/edition2023.proto b/rust/test/edition2023.proto new file mode 100644 index 0000000000..d5c48a2ff3 --- /dev/null +++ b/rust/test/edition2023.proto @@ -0,0 +1,8 @@ +edition = "2023"; + +package test; + +message EditionsMessage { + int32 plain_field = 1; + int32 implicit_presence_field = 2 [features.field_presence = IMPLICIT]; +} diff --git a/rust/test/nested.proto b/rust/test/nested.proto index 1b5b149e0c..59aee229db 100644 --- a/rust/test/nested.proto +++ b/rust/test/nested.proto @@ -11,8 +11,49 @@ package nest; message Outer { message Inner { - optional int32 num = 1; - optional bool boolean = 2; + message InnerSubMsg { + optional bool flag = 1; + } + + optional double double = 1; + optional float float = 2; + optional int32 int32 = 3; + optional int64 int64 = 4; + optional uint32 uint32 = 5; + optional uint64 uint64 = 6; + optional sint32 sint32 = 7; + optional sint64 sint64 = 8; + optional fixed32 fixed32 = 9; + optional fixed64 fixed64 = 10; + optional sfixed32 sfixed32 = 11; + optional sfixed64 sfixed64 = 12; + optional bool bool = 13; + optional string string = 14; + optional bytes bytes = 15; + optional InnerSubMsg innersubmsg = 16; + + message SuperInner { + message DuperInner { + message EvenMoreInner { + message CantBelieveItsSoInner { + optional int32 num = 99; + } + } + } + } } optional Inner inner = 1; + optional .nest.Outer.Inner.SuperInner.DuperInner.EvenMoreInner + .CantBelieveItsSoInner deep = 2; + + optional NotInside notinside = 3; +} + +message NotInside { + optional int32 num = 1; +} + +message Recursive { + optional Recursive rec = 1; + optional int32 num = 2; } diff --git a/rust/test/shared/BUILD b/rust/test/shared/BUILD index b2c4aaf164..3541f06d97 100644 --- a/rust/test/shared/BUILD +++ b/rust/test/shared/BUILD @@ -23,7 +23,7 @@ rust_library( "//rust:protobuf_upb": "protobuf", }, deps = [ - "//third_party/gtest_rust/googletest", + "@crate_index//:googletest", "//rust:protobuf_upb", ], ) @@ -35,7 +35,7 @@ rust_library( "//rust:protobuf_cpp": "protobuf", }, deps = [ - "//third_party/gtest_rust/googletest", + "@crate_index//:googletest", "//rust:protobuf_cpp", ], ) @@ -48,7 +48,7 @@ rust_test( "not_build:arm", ], deps = [ - "//third_party/gtest_rust/googletest", + "@crate_index//:googletest", "//rust/test:child_upb_rust_proto", "//rust/test:parent_upb_rust_proto", ], @@ -62,12 +62,38 @@ rust_test( "not_build:arm", ], deps = [ - "//third_party/gtest_rust/googletest", + "@crate_index//:googletest", "//rust/test:child_cc_rust_proto", "//rust/test:parent_cc_rust_proto", ], ) +rust_test( + name = "edition2023_cpp_test", + srcs = ["edition2023_test.rs"], + tags = [ + # TODO: Enable testing on arm once we support sanitizers for Rust on Arm. + "not_build:arm", + ], + deps = [ + "@crate_index//:googletest", + "//rust/test:edition2023_cc_rust_proto", + ], +) + +rust_test( + name = "edition2023_upb_test", + srcs = ["edition2023_test.rs"], + tags = [ + # TODO: Enable testing on arm once we support sanitizers for Rust on Arm. + "not_build:arm", + ], + deps = [ + "@crate_index//:googletest", + "//rust/test:edition2023_upb_rust_proto", + ], +) + rust_test( name = "package_cpp_test", srcs = ["package_test.rs"], @@ -104,7 +130,7 @@ rust_test( "not_build:arm", ], deps = [ - "//third_party/gtest_rust/googletest", + "@crate_index//:googletest", "//rust/test:reserved_cc_rust_proto", "//rust/test:unittest_cc_rust_proto", ], @@ -118,7 +144,7 @@ rust_test( "not_build:arm", ], deps = [ - "//third_party/gtest_rust/googletest", + "@crate_index//:googletest", "//rust/test:reserved_upb_rust_proto", "//rust/test:unittest_upb_rust_proto", ], @@ -159,7 +185,7 @@ rust_test( "not_build:arm", ], deps = [ - "//third_party/gtest_rust/googletest", + "@crate_index//:googletest", "//rust:protobuf_cpp", "//rust/test:unittest_cc_rust_proto", "//rust/test/shared:matchers_cpp", @@ -181,7 +207,7 @@ rust_test( "not_build:arm", ], deps = [ - "//third_party/gtest_rust/googletest", + "@crate_index//:googletest", "//rust:protobuf_upb", "//rust/test:unittest_upb_rust_proto", "//rust/test/shared:matchers_upb", @@ -200,7 +226,7 @@ rust_test( "not_build:arm", ], deps = [ - "//third_party/gtest_rust/googletest", + "@crate_index//:googletest", "//rust:protobuf_cpp", "//rust/test:unittest_proto3_cc_rust_proto", "//rust/test:unittest_proto3_optional_cc_rust_proto", @@ -220,7 +246,7 @@ rust_test( "not_build:arm", ], deps = [ - "//third_party/gtest_rust/googletest", + "@crate_index//:googletest", "//rust:protobuf_upb", "//rust/test:unittest_proto3_optional_upb_rust_proto", "//rust/test:unittest_proto3_upb_rust_proto", @@ -236,7 +262,7 @@ rust_test( "not_build:arm", ], deps = [ - "//third_party/gtest_rust/googletest", + "@crate_index//:googletest", "//rust/test:unittest_upb_rust_proto", ], ) @@ -249,7 +275,7 @@ rust_test( "not_build:arm", ], deps = [ - "//third_party/gtest_rust/googletest", + "@crate_index//:googletest", "//rust/test:unittest_cc_rust_proto", ], ) @@ -257,11 +283,97 @@ rust_test( rust_test( name = "simple_nested_cpp_test", srcs = ["simple_nested_test.rs"], - deps = ["//rust/test:nested_cc_rust_proto"], + tags = [ + # TODO: Enable testing on arm once we support sanitizers for Rust on Arm. + "not_build:arm", + ], + deps = [ + "@crate_index//:googletest", + "//rust/test:nested_cc_rust_proto", + ], ) rust_test( name = "simple_nested_upb_test", srcs = ["simple_nested_test.rs"], - deps = ["//rust/test:nested_upb_rust_proto"], + tags = [ + # TODO: Enable testing on arm once we support sanitizers for Rust on Arm. + "not_build:arm", + ], + deps = [ + "@crate_index//:googletest", + "//rust/test:nested_upb_rust_proto", + ], +) + +rust_test( + name = "accessors_repeated_cpp_test", + srcs = ["accessors_repeated_test.rs"], + aliases = { + "//rust:protobuf_cpp": "protobuf", + }, + proc_macro_deps = [ + "@crate_index//:paste", + ], + tags = [ + # TODO: Enable testing on arm once we support sanitizers for Rust on Arm. + "not_build:arm", + ], + deps = [ + "@crate_index//:googletest", + "//rust:protobuf_cpp", + "//rust/test:unittest_cc_rust_proto", + ], +) + +rust_test( + name = "accessors_repeated_upb_test", + srcs = ["accessors_repeated_test.rs"], + aliases = { + "//rust:protobuf_upb": "protobuf", + }, + proc_macro_deps = [ + "@crate_index//:paste", + ], + tags = [ + # TODO: Enable testing on arm once we support sanitizers for Rust on Arm. + "not_build:arm", + ], + deps = [ + "@crate_index//:googletest", + "//rust:protobuf_upb", + "//rust/test:unittest_upb_rust_proto", + ], +) + +rust_test( + name = "accessors_map_cpp_test", + srcs = ["accessors_map_test.rs"], + proc_macro_deps = [ + "@crate_index//:paste", + ], + tags = [ + # TODO: Enable testing on arm once we support sanitizers for Rust on Arm. + "not_build:arm", + ], + deps = [ + "@crate_index//:googletest", + "//rust/test:map_unittest_cc_rust_proto", + ], +) + +rust_test( + name = "accessors_map_upb_test", + srcs = ["accessors_map_test.rs"], + proc_macro_deps = [ + "@crate_index//:paste", + ], + tags = [ + # TODO: Enable testing on arm once we support sanitizers for Rust on Arm. + "not_build:arm", + ], + deps = [ + "@crate_index//:googletest", + "//rust/test:map_unittest_upb_rust_proto", + ], ) diff --git a/rust/test/shared/accessors_map_test.rs b/rust/test/shared/accessors_map_test.rs new file mode 100644 index 0000000000..ecdd35a20a --- /dev/null +++ b/rust/test/shared/accessors_map_test.rs @@ -0,0 +1,55 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google LLC. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +use googletest::prelude::*; +use map_unittest_proto::proto2_unittest::TestMap; +use paste::paste; + +macro_rules! generate_map_primitives_tests { + ( + $(($k_type:ty, $v_type:ty, $k_field:ident, $v_field:ident)),* + ) => { + paste! { $( + #[test] + fn [< test_map_ $k_field _ $v_field >]() { + let mut msg = TestMap::new(); + let k: $k_type = Default::default(); + let v: $v_type = Default::default(); + assert_that!(msg.[< map_ $k_field _ $v_field _mut>]().insert(k, v), eq(true)); + assert_that!(msg.[< map_ $k_field _ $v_field >]().len(), eq(1)); + } + )* } + }; +} + +generate_map_primitives_tests!( + (i32, i32, int32, int32), + (i64, i64, int64, int64), + (u32, u32, uint32, uint32), + (u64, u64, uint64, uint64), + (i32, i32, sint32, sint32), + (i64, i64, sint64, sint64), + (u32, u32, fixed32, fixed32), + (u64, u64, fixed64, fixed64), + (i32, i32, sfixed32, sfixed32), + (i64, i64, sfixed64, sfixed64), + (i32, f32, int32, float), + (i32, f64, int32, double), + (bool, bool, bool, bool) +); + +#[test] +fn test_string_maps() { + let mut msg = TestMap::new(); + msg.map_string_string_mut().insert("hello", "world".into()); + msg.map_string_string_mut().insert("fizz", "buzz".into()); + assert_that!(msg.map_string_string().len(), eq(2)); + assert_that!(msg.map_string_string().get("fizz").unwrap(), eq("buzz")); + assert_that!(msg.map_string_string().get("not found"), eq(None)); + msg.map_string_string_mut().clear(); + assert_that!(msg.map_string_string().len(), eq(0)); +} diff --git a/rust/test/shared/accessors_proto3_test.rs b/rust/test/shared/accessors_proto3_test.rs index 3260c0d11d..5ae20143ff 100644 --- a/rust/test/shared/accessors_proto3_test.rs +++ b/rust/test/shared/accessors_proto3_test.rs @@ -23,9 +23,13 @@ fn test_fixed32_accessors() { assert_that!(msg.optional_fixed32_mut().get(), eq(42)); assert_that!(msg.optional_fixed32(), eq(42)); - msg.optional_fixed32_mut().clear(); + msg.optional_fixed32_mut().set(u32::default()); assert_that!(msg.optional_fixed32(), eq(0)); assert_that!(msg.optional_fixed32_mut().get(), eq(0)); + + msg.optional_fixed32_set(43); + assert_that!(msg.optional_fixed32(), eq(43)); + assert_that!(msg.optional_fixed32_mut().get(), eq(43)); } #[test] @@ -38,9 +42,13 @@ fn test_bool_accessors() { assert_that!(msg.optional_bool(), eq(true)); assert_that!(msg.optional_bool_mut().get(), eq(true)); - msg.optional_bool_mut().clear(); + msg.optional_bool_mut().set(bool::default()); assert_that!(msg.optional_bool(), eq(false)); assert_that!(msg.optional_bool_mut().get(), eq(false)); + + msg.optional_bool_set(true); + assert_that!(msg.optional_bool(), eq(true)); + assert_that!(msg.optional_bool_mut().get(), eq(true)); } #[test] @@ -122,66 +130,66 @@ fn test_string_accessors() { let mut msg = TestAllTypes::new(); // Note: even though it's named 'optional_string', the field is actually not // proto3 optional, so it does not support presence. - assert_eq!(msg.optional_string(), ""); - assert_eq!(msg.optional_string_mut().get(), ""); + assert_that!(*msg.optional_string().as_bytes(), empty()); + assert_that!(*msg.optional_string_mut().get().as_bytes(), empty()); msg.optional_string_mut().set("accessors_test"); - assert_eq!(msg.optional_string(), "accessors_test"); - assert_eq!(msg.optional_string_mut().get(), "accessors_test"); + assert_that!(msg.optional_string(), eq("accessors_test")); + assert_that!(msg.optional_string_mut().get(), eq("accessors_test")); { let s = String::from("hello world"); msg.optional_string_mut().set(&s[..]); } - assert_eq!(msg.optional_string(), "hello world"); - assert_eq!(msg.optional_string_mut().get(), "hello world"); + assert_that!(msg.optional_string(), eq("hello world")); + assert_that!(msg.optional_string_mut().get(), eq("hello world")); msg.optional_string_mut().clear(); - assert_eq!(msg.optional_string(), ""); - assert_eq!(msg.optional_string_mut().get(), ""); + assert_that!(*msg.optional_string().as_bytes(), empty()); + assert_that!(*msg.optional_string_mut().get().as_bytes(), empty()); msg.optional_string_mut().set(""); - assert_eq!(msg.optional_string(), ""); - assert_eq!(msg.optional_string_mut().get(), ""); + assert_that!(*msg.optional_string().as_bytes(), empty()); + assert_that!(*msg.optional_string_mut().get().as_bytes(), empty()); } #[test] fn test_optional_string_accessors() { let mut msg = TestProto3Optional::new(); - assert_eq!(msg.optional_string(), ""); - assert_eq!(msg.optional_string_opt(), Optional::Unset("".into())); - assert_eq!(msg.optional_string_mut().get(), ""); + assert_that!(*msg.optional_string().as_bytes(), empty()); + assert_that!(msg.optional_string_opt(), eq(Optional::Unset("".into()))); + assert_that!(*msg.optional_string_mut().get().as_bytes(), empty()); assert_that!(msg.optional_string_mut(), is_unset()); { let s = String::from("hello world"); msg.optional_string_mut().set(&s[..]); } - assert_eq!(msg.optional_string(), "hello world"); - assert_eq!(msg.optional_string_opt(), Optional::Set("hello world".into())); + assert_that!(msg.optional_string(), eq("hello world")); + assert_that!(msg.optional_string_opt(), eq(Optional::Set("hello world".into()))); assert_that!(msg.optional_string_mut(), is_set()); - assert_eq!(msg.optional_string_mut().get(), "hello world"); + assert_that!(msg.optional_string_mut().get(), eq("hello world")); msg.optional_string_mut().or_default().set("accessors_test"); - assert_eq!(msg.optional_string(), "accessors_test"); - assert_eq!(msg.optional_string_opt(), Optional::Set("accessors_test".into())); + assert_that!(msg.optional_string(), eq("accessors_test")); + assert_that!(msg.optional_string_opt(), eq(Optional::Set("accessors_test".into()))); assert_that!(msg.optional_string_mut(), is_set()); - assert_eq!(msg.optional_string_mut().get(), "accessors_test"); - assert_eq!(msg.optional_string_mut().or_default().get(), "accessors_test"); + assert_that!(msg.optional_string_mut().get(), eq("accessors_test")); + assert_that!(msg.optional_string_mut().or_default().get(), eq("accessors_test")); msg.optional_string_mut().clear(); - assert_eq!(msg.optional_string(), ""); - assert_eq!(msg.optional_string_opt(), Optional::Unset("".into())); + assert_that!(*msg.optional_string().as_bytes(), empty()); + assert_that!(msg.optional_string_opt(), eq(Optional::Unset("".into()))); assert_that!(msg.optional_string_mut(), is_unset()); msg.optional_string_mut().set(""); - assert_eq!(msg.optional_string(), ""); - assert_eq!(msg.optional_string_opt(), Optional::Set("".into())); + assert_that!(*msg.optional_string().as_bytes(), empty()); + assert_that!(msg.optional_string_opt(), eq(Optional::Set("".into()))); msg.optional_string_mut().clear(); msg.optional_string_mut().or_default(); - assert_eq!(msg.optional_string(), ""); - assert_eq!(msg.optional_string_opt(), Optional::Set("".into())); + assert_that!(*msg.optional_string().as_bytes(), empty()); + assert_that!(msg.optional_string_opt(), eq(Optional::Set("".into()))); } #[test] @@ -199,10 +207,55 @@ fn test_oneof_accessors() { assert_that!(msg.oneof_uint32_opt(), eq(Optional::Unset(0))); assert_that!(msg.oneof_field(), matches_pattern!(not_set(_))); + // TODO: the submessage api is still in progress so we can't yet + // cause a submsg to be set here. + + // msg.oneof_nested_message_mut().or_default(); // Cause the nested_message + // field to become set. + + // assert_that!(msg.oneof_bytes_opt(), + // eq(Optional::Unset(_))); assert_that!(msg.oneof_field(), + // matches_pattern!(OneofNestedMessage(_))); + msg.oneof_uint32_set(Some(7)); - msg.oneof_bytes_mut().set(b""); + msg.oneof_bytes_mut().set(b"123"); assert_that!(msg.oneof_uint32_opt(), eq(Optional::Unset(0))); + assert_that!(msg.oneof_field(), matches_pattern!(OneofBytes(eq(b"123")))); - // This should show it set to the OneofBytes but its not supported yet. + msg.oneof_bytes_mut().clear(); assert_that!(msg.oneof_field(), matches_pattern!(not_set(_))); } + +#[test] +fn test_oneof_mut_accessors() { + use TestAllTypes_::OneofFieldMut::*; + + let mut msg = TestAllTypes::new(); + assert_that!(msg.oneof_field_mut(), matches_pattern!(not_set(_))); + + msg.oneof_uint32_set(Some(7)); + + match msg.oneof_field_mut() { + OneofUint32(mut v) => { + assert_eq!(v.get(), 7); + v.set(8); + assert_eq!(v.get(), 8); + } + f => panic!("unexpected field_mut type! {:?}", f), + } + + // Confirm that the mut write above applies to both the field accessor and the + // oneof view accessor. + assert_that!(msg.oneof_uint32_opt(), eq(Optional::Set(8))); + assert_that!( + msg.oneof_field(), + matches_pattern!(TestAllTypes_::OneofField::OneofUint32(eq(8))) + ); + + msg.oneof_uint32_set(None); + assert_that!(msg.oneof_field_mut(), matches_pattern!(not_set(_))); + + msg.oneof_uint32_set(Some(7)); + msg.oneof_bytes_mut().set(b"123"); + assert_that!(msg.oneof_field_mut(), matches_pattern!(OneofBytes(_))); +} diff --git a/rust/test/shared/accessors_repeated_test.rs b/rust/test/shared/accessors_repeated_test.rs new file mode 100644 index 0000000000..d0b9a3bc42 --- /dev/null +++ b/rust/test/shared/accessors_repeated_test.rs @@ -0,0 +1,122 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google LLC. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +use googletest::prelude::*; +use paste::paste; +use unittest_proto::proto2_unittest::TestAllTypes; + +macro_rules! generate_repeated_numeric_test { + ($(($t: ty, $field: ident)),*) => { + paste! { $( + #[test] + fn [< test_repeated_ $field _accessors >]() { + let mut msg = TestAllTypes::new(); + assert_that!(msg.[< repeated_ $field >]().len(), eq(0)); + assert_that!(msg.[]().get(0), none()); + + let mut mutator = msg.[](); + mutator.push(1 as $t); + assert_that!(mutator.len(), eq(1)); + assert_that!(mutator.get(0), some(eq(1 as $t))); + mutator.set(0, 2 as $t); + assert_that!(mutator.get(0), some(eq(2 as $t))); + mutator.push(1 as $t); + + mutator.push(3 as $t); + mutator.set(2, 4 as $t); + assert_that!(mutator.get(2), some(eq(4 as $t))); + mutator.set(2, 0 as $t); + + assert_that!( + mutator.iter().collect::>(), + eq(vec![2 as $t, 1 as $t, 0 as $t]) + ); + assert_that!( + (*mutator).into_iter().collect::>(), + eq(vec![2 as $t, 1 as $t, 0 as $t]) + ); + + for i in 0..mutator.len() { + mutator.set(i, 0 as $t); + } + assert_that!( + msg.[]().iter().all(|v| v == (0 as $t)), + eq(true) + ); + } + + #[test] + fn [< test_repeated_ $field _set >]() { + let mut msg = TestAllTypes::new(); + let mut mutator = msg.[](); + let mut msg2 = TestAllTypes::new(); + let mut mutator2 = msg2.[](); + for i in 0..5 { + mutator2.push(i as $t); + } + protobuf::MutProxy::set(&mut mutator, *mutator2); + + assert_that!( + mutator.iter().collect::>(), + eq(mutator2.iter().collect::>()) + ); + } + )* } + }; +} + +generate_repeated_numeric_test!( + (i32, int32), + (u32, uint32), + (i64, int64), + (u64, uint64), + (f32, float), + (f64, double) +); + +#[test] +fn test_repeated_bool_accessors() { + let mut msg = TestAllTypes::new(); + assert_that!(msg.repeated_bool().len(), eq(0)); + assert_that!(msg.repeated_bool().get(0), none()); + + let mut mutator = msg.repeated_bool_mut(); + mutator.push(true); + assert_that!(mutator.len(), eq(1)); + assert_that!(mutator.get(0), some(eq(true))); + mutator.set(0, false); + assert_that!(mutator.get(0), some(eq(false))); + mutator.push(true); + + mutator.push(false); + mutator.set(2, true); + assert_that!(mutator.get(2), some(eq(true))); + mutator.set(2, false); + assert_that!(mutator.get(2), some(eq(false))); + + assert_that!(mutator.iter().collect::>(), eq(vec![false, true, false])); + assert_that!((*mutator).into_iter().collect::>(), eq(vec![false, true, false])); + + for i in 0..mutator.len() { + mutator.set(i, false); + } + assert_that!(msg.repeated_bool().iter().all(|v| v), eq(false)); +} + +#[test] +fn test_repeated_bool_set() { + let mut msg = TestAllTypes::new(); + let mut mutator = msg.repeated_bool_mut(); + let mut msg2 = TestAllTypes::new(); + let mut mutator2 = msg2.repeated_bool_mut(); + for _ in 0..5 { + mutator2.push(true); + } + protobuf::MutProxy::set(&mut mutator, *mutator2); + + assert_that!(mutator.iter().collect::>(), eq(mutator2.iter().collect::>())); +} diff --git a/rust/test/shared/accessors_test.rs b/rust/test/shared/accessors_test.rs index f1f55f663d..0fbb535ee5 100644 --- a/rust/test/shared/accessors_test.rs +++ b/rust/test/shared/accessors_test.rs @@ -9,7 +9,6 @@ use googletest::prelude::*; use matchers::{is_set, is_unset}; -use paste::paste; use protobuf::Optional; use unittest_proto::proto2_unittest::{TestAllTypes, TestAllTypes_}; @@ -34,6 +33,8 @@ fn test_default_accessors() { default_bool(): eq(true), }) ); + assert_that!(msg.default_string(), eq("hello")); + assert_that!(msg.default_bytes(), eq("world".as_bytes())); } #[test] @@ -667,11 +668,16 @@ fn test_nonempty_default_string_accessors() { #[test] fn test_singular_msg_field() { - use crate::TestAllTypes_::NestedMessageView; - let msg = TestAllTypes::new(); - // TODO: fetch the inner integer `bb` - // call should look like msg.optional_nested_message().bb() - let _msg: NestedMessageView = msg.optional_nested_message(); + use crate::TestAllTypes_::{NestedMessageMut, NestedMessageView}; + + let mut msg = TestAllTypes::new(); + let msg_view: NestedMessageView = msg.optional_nested_message(); + // testing reading an int inside a view + assert_that!(msg_view.bb(), eq(0)); + + let msg_mut: NestedMessageMut = msg.optional_nested_message_mut(); + // test reading an int inside a mut + assert_that!(msg_mut.bb(), eq(0)); } #[test] @@ -690,126 +696,42 @@ fn test_oneof_accessors() { assert_that!(msg.oneof_field(), matches_pattern!(not_set(_))); msg.oneof_uint32_set(Some(7)); - msg.oneof_bytes_mut().set(b""); + msg.oneof_bytes_mut().set(b"123"); assert_that!(msg.oneof_uint32_opt(), eq(Optional::Unset(0))); - // This should show it set to the OneofBytes but its not supported yet. - assert_that!(msg.oneof_field(), matches_pattern!(not_set(_))); + assert_that!(msg.oneof_field(), matches_pattern!(OneofBytes(eq(b"123")))); } -macro_rules! generate_repeated_numeric_test { - ($(($t: ty, $field: ident)),*) => { - paste! { $( - #[test] - fn [< test_repeated_ $field _accessors >]() { - let mut msg = TestAllTypes::new(); - assert_that!(msg.[< repeated_ $field >]().len(), eq(0)); - assert_that!(msg.[]().get(0), none()); - - let mut mutator = msg.[](); - mutator.push(1 as $t); - assert_that!(mutator.len(), eq(1)); - assert_that!(mutator.get(0), some(eq(1 as $t))); - mutator.set(0, 2 as $t); - assert_that!(mutator.get(0), some(eq(2 as $t))); - mutator.push(1 as $t); - - mutator.push(3 as $t); - assert_that!(mutator.get_mut(2).is_some(), eq(true)); - let mut mut_elem = mutator.get_mut(2).unwrap(); - mut_elem.set(4 as $t); - assert_that!(mut_elem.get(), eq(4 as $t)); - mut_elem.clear(); - assert_that!(mut_elem.get(), eq(0 as $t)); - - assert_that!( - mutator.iter().collect::>(), - eq(vec![2 as $t, 1 as $t, 0 as $t]) - ); - assert_that!( - (*mutator).into_iter().collect::>(), - eq(vec![2 as $t, 1 as $t, 0 as $t]) - ); - - for mut mutable_elem in msg.[]() { - mutable_elem.set(0 as $t); - } - assert_that!( - msg.[]().iter().all(|v| v == (0 as $t)), - eq(true) - ); - } - - #[test] - fn [< test_repeated_ $field _set >]() { - let mut msg = TestAllTypes::new(); - let mut mutator = msg.[](); - let mut msg2 = TestAllTypes::new(); - let mut mutator2 = msg2.[](); - for i in 0..5 { - mutator2.push(i as $t); - } - protobuf::MutProxy::set(&mut mutator, *mutator2); - - assert_that!( - mutator.iter().collect::>(), - eq(mutator2.iter().collect::>()) - ); - } - )* } - }; -} - -generate_repeated_numeric_test!( - (i32, int32), - (u32, uint32), - (i64, int64), - (u64, uint64), - (f32, float), - (f64, double) -); - #[test] -fn test_repeated_bool_accessors() { - let mut msg = TestAllTypes::new(); - assert_that!(msg.repeated_bool().len(), eq(0)); - assert_that!(msg.repeated_bool().get(0), none()); - - let mut mutator = msg.repeated_bool_mut(); - mutator.push(true); - assert_that!(mutator.len(), eq(1)); - assert_that!(mutator.get(0), some(eq(true))); - mutator.set(0, false); - assert_that!(mutator.get(0), some(eq(false))); - mutator.push(true); - - mutator.push(false); - assert_that!(mutator.get_mut(2), pat!(Some(_))); - let mut mut_elem = mutator.get_mut(2).unwrap(); - mut_elem.set(true); - assert_that!(mut_elem.get(), eq(true)); - mut_elem.clear(); - assert_that!(mut_elem.get(), eq(false)); - - assert_that!(mutator.iter().collect::>(), eq(vec![false, true, false])); - assert_that!((*mutator).into_iter().collect::>(), eq(vec![false, true, false])); - - for mut mutable_elem in msg.repeated_bool_mut() { - mutable_elem.set(false); - } - assert_that!(msg.repeated_bool().iter().all(|v| v), eq(false)); -} +fn test_oneof_mut_accessors() { + use TestAllTypes_::OneofFieldMut::*; -#[test] -fn test_repeated_bool_set() { let mut msg = TestAllTypes::new(); - let mut mutator = msg.repeated_bool_mut(); - let mut msg2 = TestAllTypes::new(); - let mut mutator2 = msg2.repeated_bool_mut(); - for _ in 0..5 { - mutator2.push(true); + assert_that!(msg.oneof_field_mut(), matches_pattern!(not_set(_))); + + msg.oneof_uint32_set(Some(7)); + + match msg.oneof_field_mut() { + OneofUint32(mut v) => { + assert_eq!(v.get(), 7); + v.set(8); + assert_eq!(v.get(), 8); + } + f => panic!("unexpected field_mut type! {:?}", f), } - protobuf::MutProxy::set(&mut mutator, *mutator2); - assert_that!(mutator.iter().collect::>(), eq(mutator2.iter().collect::>())); + // Confirm that the mut write above applies to both the field accessor and the + // oneof view accessor. + assert_that!(msg.oneof_uint32_opt(), eq(Optional::Set(8))); + assert_that!( + msg.oneof_field(), + matches_pattern!(TestAllTypes_::OneofField::OneofUint32(eq(8))) + ); + + msg.oneof_uint32_set(None); + assert_that!(msg.oneof_field_mut(), matches_pattern!(not_set(_))); + + msg.oneof_uint32_set(Some(7)); + msg.oneof_bytes_mut().set(b"123"); + assert_that!(msg.oneof_field_mut(), matches_pattern!(OneofBytes(_))); } diff --git a/rust/test/shared/edition2023_test.rs b/rust/test/shared/edition2023_test.rs new file mode 100644 index 0000000000..f5f631a825 --- /dev/null +++ b/rust/test/shared/edition2023_test.rs @@ -0,0 +1,23 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google LLC. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +use googletest::prelude::*; + +// Tests that an proto file that declares edition="2023" works. Note that this +// is _not_ a test for Rust Edition 2023 (which doesn't exist) but instead +// Protobuf Edition 2023 (which exists). + +#[test] +fn check_edition2023_works() { + let mut msg = edition2023_proto::test::EditionsMessage::new(); + + // plain_field supports presence. + assert_that!(msg.plain_field_mut().or_default().get(), eq(0)); + + // implicit presence fields' _mut() skips FieldEntry. + assert_that!(msg.implicit_presence_field_mut().get(), eq(0)); +} diff --git a/rust/test/shared/simple_nested_test.rs b/rust/test/shared/simple_nested_test.rs index 2f9dad50b4..1fe175a8b4 100644 --- a/rust/test/shared/simple_nested_test.rs +++ b/rust/test/shared/simple_nested_test.rs @@ -5,11 +5,113 @@ // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd +use googletest::prelude::*; use nested_proto::nest::Outer; +use nested_proto::nest::Outer_::InnerMut; +use nested_proto::nest::Outer_::InnerView; #[test] -fn test_simple_nested_proto() { +fn test_deeply_nested_definition() { + let deep = nested_proto::nest::Outer_::Inner_::SuperInner_::DuperInner_::EvenMoreInner_ + ::CantBelieveItsSoInner::new(); + assert_that!(deep.num(), eq(0)); + + let outer_msg = Outer::new(); + assert_that!(outer_msg.deep().num(), eq(0)); +} + +#[test] +fn test_nested_views() { let outer_msg = Outer::new(); - assert_eq!(outer_msg.inner().num(), 0); - assert!(!outer_msg.inner().boolean()); + let inner_msg: InnerView<'_> = outer_msg.inner(); + assert_that!(inner_msg.double(), eq(0.0)); + assert_that!(inner_msg.float(), eq(0.0)); + assert_that!(inner_msg.int32(), eq(0)); + assert_that!(inner_msg.int64(), eq(0)); + assert_that!(inner_msg.uint32(), eq(0)); + assert_that!(inner_msg.uint64(), eq(0)); + assert_that!(inner_msg.sint32(), eq(0)); + assert_that!(inner_msg.sint64(), eq(0)); + assert_that!(inner_msg.fixed32(), eq(0)); + assert_that!(inner_msg.fixed64(), eq(0)); + assert_that!(inner_msg.sfixed32(), eq(0)); + assert_that!(inner_msg.sfixed64(), eq(0)); + assert_that!(inner_msg.bool(), eq(false)); + assert_that!(*inner_msg.string().as_bytes(), empty()); + assert_that!(*inner_msg.bytes(), empty()); + assert_that!(inner_msg.innersubmsg().flag(), eq(false)); +} + +#[test] +fn test_nested_muts() { + // Covers the setting of a mut and the following assertion + // confirming the new value. Replacement example: + // old: + // inner_msg.double_mut().set(543.21); + // assert_that!(inner_msg.double_mut().get(), eq(543.21)); + // new: + // set_and_test_mut!(inner_msg => double_mut, 543.21); + macro_rules! set_and_test_mut { + ( $a:expr => $($target_mut:ident, $val:literal;)* ) => { + $( + $a.$target_mut().set($val); + assert_that!($a.$target_mut().get(), eq($val)); + )* + }; +} + + let mut outer_msg = Outer::new(); + let inner_msg: InnerMut<'_> = outer_msg.inner_mut(); + assert_that!( + inner_msg, + matches_pattern!(InnerMut{ + float(): eq(0.0), + double(): eq(0.0), + int32(): eq(0), + int64(): eq(0), + uint32(): eq(0), + uint64(): eq(0), + sint32(): eq(0), + sint64(): eq(0), + fixed32(): eq(0), + fixed64(): eq(0), + sfixed32(): eq(0), + sfixed64(): eq(0), + bool(): eq(false) + }) + ); + assert_that!(inner_msg.string_mut().get(), eq("")); + + set_and_test_mut!(inner_msg => + double_mut, 543.21; + float_mut, 1.23; + int32_mut, 12; + int64_mut, 42; + uint32_mut, 13; + uint64_mut, 5000; + sint32_mut, -2; + sint64_mut, 322; + fixed32_mut, 77; + fixed64_mut, 999; + bool_mut, true; + string_mut, "hi"; + ); + // TODO: add mutation test for bytes +} + +#[test] +fn test_msg_from_outside() { + // let's make sure that we're not just working for messages nested inside + // messages, messages from without and within should work + let outer = nested_proto::nest::Outer::new(); + assert_that!(outer.notinside().num(), eq(0)); +} + +#[test] +fn test_recursive_msg() { + let rec = nested_proto::nest::Recursive::new(); + assert_that!(rec.num(), eq(0)); + assert_that!(rec.rec().num(), eq(0)); + assert_that!(rec.rec().rec().num(), eq(0)); // turtles all the way down... + assert_that!(rec.rec().rec().rec().num(), eq(0)); // ... ad infinitum } diff --git a/rust/upb.rs b/rust/upb.rs index b6fd7b322a..f618406467 100644 --- a/rust/upb.rs +++ b/rust/upb.rs @@ -7,13 +7,16 @@ //! UPB FFI wrapper code for use by Rust Protobuf. -use crate::__internal::{Private, PtrAndLen, RawArena, RawMessage, RawRepeatedField}; +use crate::ProtoStr; +use crate::__internal::{Private, PtrAndLen, RawArena, RawMap, RawMessage, RawRepeatedField}; +use core::fmt::Debug; +use paste::paste; use std::alloc; use std::alloc::Layout; use std::cell::UnsafeCell; use std::fmt; use std::marker::PhantomData; -use std::mem::MaybeUninit; +use std::mem::{size_of, MaybeUninit}; use std::ops::Deref; use std::ptr::{self, NonNull}; use std::slice; @@ -214,7 +217,7 @@ impl fmt::Debug for SerializedData { pub type BytesPresentMutData<'msg> = crate::vtable::RawVTableOptionalMutatorData<'msg, [u8]>; pub type BytesAbsentMutData<'msg> = crate::vtable::RawVTableOptionalMutatorData<'msg, [u8]>; pub type InnerBytesMut<'msg> = crate::vtable::RawVTableMutator<'msg, [u8]>; -pub type InnerPrimitiveMut<'a, T> = crate::vtable::RawVTableMutator<'a, T>; +pub type InnerPrimitiveMut<'msg, T> = crate::vtable::RawVTableMutator<'msg, T>; /// The raw contents of every generated message. #[derive(Debug)] @@ -261,15 +264,23 @@ impl<'msg> MutatorMessageRef<'msg> { MutatorMessageRef { msg: msg.msg, arena: &msg.arena } } + pub fn from_parent( + _private: Private, + parent_msg: &'msg mut MessageInner, + message_field_ptr: RawMessage, + ) -> Self { + MutatorMessageRef { msg: message_field_ptr, arena: &parent_msg.arena } + } + pub fn msg(&self) -> RawMessage { self.msg } } -pub fn copy_bytes_in_arena_if_needed_by_runtime<'a>( - msg_ref: MutatorMessageRef<'a>, - val: &'a [u8], -) -> &'a [u8] { +pub fn copy_bytes_in_arena_if_needed_by_runtime<'msg>( + msg_ref: MutatorMessageRef<'msg>, + val: &'msg [u8], +) -> &'msg [u8] { // SAFETY: the alignment of `[u8]` is less than `UPB_MALLOC_ALIGN`. let new_alloc = unsafe { msg_ref.arena.alloc(Layout::for_value(val)) }; debug_assert_eq!(new_alloc.len(), val.len()); @@ -324,7 +335,7 @@ impl<'msg, T: ?Sized> RepeatedField<'msg, T> { // Transcribed from google3/third_party/upb/upb/message/value.h #[repr(C)] #[derive(Clone, Copy)] -union upb_MessageValue { +pub union upb_MessageValue { bool_val: bool, float_val: std::ffi::c_float, double_val: std::ffi::c_double, @@ -341,7 +352,7 @@ union upb_MessageValue { // Transcribed from google3/third_party/upb/upb/base/descriptor_constants.h #[repr(C)] #[allow(dead_code)] -enum UpbCType { +pub enum UpbCType { Bool = 1, Float = 2, Int32 = 3, @@ -362,11 +373,13 @@ extern "C" { fn upb_Array_Set(arr: RawRepeatedField, i: usize, val: upb_MessageValue); fn upb_Array_Get(arr: RawRepeatedField, i: usize) -> upb_MessageValue; fn upb_Array_Append(arr: RawRepeatedField, val: upb_MessageValue, arena: RawArena); - fn upb_Array_Resize(arr: RawRepeatedField, size: usize, arena: RawArena); + fn upb_Array_Resize(arr: RawRepeatedField, size: usize, arena: RawArena) -> bool; + fn upb_Array_MutableDataPtr(arr: RawRepeatedField) -> *mut std::ffi::c_void; + fn upb_Array_DataPtr(arr: RawRepeatedField) -> *const std::ffi::c_void; } macro_rules! impl_repeated_primitives { - ($(($rs_type:ty, $union_field:ident, $upb_tag:expr)),*) => { + ($(($rs_type:ty, $ufield:ident, $upb_tag:expr)),*) => { $( impl<'msg> RepeatedField<'msg, $rs_type> { #[allow(dead_code)] @@ -382,7 +395,7 @@ macro_rules! impl_repeated_primitives { pub fn push(&mut self, val: $rs_type) { unsafe { upb_Array_Append( self.inner.raw, - upb_MessageValue { $union_field: val }, + upb_MessageValue { $ufield: val }, self.inner.arena.raw(), ) } } @@ -390,7 +403,7 @@ macro_rules! impl_repeated_primitives { if i >= self.len() { None } else { - unsafe { Some(upb_Array_Get(self.inner.raw, i).$union_field) } + unsafe { Some(upb_Array_Get(self.inner.raw, i).$ufield) } } } pub fn set(&self, i: usize, val: $rs_type) { @@ -400,20 +413,22 @@ macro_rules! impl_repeated_primitives { unsafe { upb_Array_Set( self.inner.raw, i, - upb_MessageValue { $union_field: val }, + upb_MessageValue { $ufield: val }, ) } } pub fn copy_from(&mut self, src: &RepeatedField<'_, $rs_type>) { - // TODO: Optimize this copy_from implementation using memcopy. - // NOTE: `src` cannot be `self` because this would violate borrowing rules. - unsafe { upb_Array_Resize(self.inner.raw, 0, self.inner.arena.raw()) }; - // `upb_Array_DeepClone` is not used here because it returns - // a new `upb_Array*`. The contained `RawRepeatedField` must - // then be set to this new pointer, but other copies of this - // pointer may exist because of re-borrowed `RepeatedMut`s. - // Alternatively, a `clone_into` method could be exposed by upb. - for i in 0..src.len() { - self.push(src.get(i).unwrap()); + // SAFETY: + // - `upb_Array_Resize` is unsafe but assumed to be always sound to call. + // - `copy_nonoverlapping` is unsafe but here we guarantee that both pointers + // are valid, the pointers are `#[repr(u8)]`, and the size is correct. + unsafe { + if (!upb_Array_Resize(self.inner.raw, src.len(), self.inner.arena.raw())) { + panic!("upb_Array_Resize failed."); + } + ptr::copy_nonoverlapping( + upb_Array_DataPtr(src.inner.raw).cast::(), + upb_Array_MutableDataPtr(self.inner.raw).cast::(), + size_of::<$rs_type>() * src.len()); } } } @@ -435,6 +450,8 @@ impl_repeated_primitives!( /// RepeatedView. /// /// # Safety +/// The returned array must never be mutated. +/// /// TODO: Split RepeatedFieldInner into mut and const variants to /// enforce safety. The returned array must never be mutated. pub unsafe fn empty_array() -> RepeatedFieldInner<'static> { @@ -451,9 +468,237 @@ pub unsafe fn empty_array() -> RepeatedFieldInner<'static> { REPEATED_FIELD.with(|inner| *inner) } +/// Returns a static thread-local empty MapInner for use in a +/// MapView. +/// +/// # Safety +/// The returned map must never be mutated. +/// +/// TODO: Split MapInner into mut and const variants to +/// enforce safety. The returned array must never be mutated. +pub unsafe fn empty_map() -> MapInner<'static, K, V> { + fn new_map_inner() -> MapInner<'static, i32, i32> { + // TODO: Consider creating empty map in C. + let arena = Box::leak::<'static>(Box::new(Arena::new())); + // Provide `i32` as a placeholder type. + MapInner::<'static, i32, i32>::new(arena) + } + thread_local! { + static MAP: MapInner<'static, i32, i32> = new_map_inner(); + } + + MAP.with(|inner| MapInner { + raw: inner.raw, + arena: inner.arena, + _phantom_key: PhantomData, + _phantom_value: PhantomData, + }) +} + +#[derive(Debug)] +pub struct MapInner<'msg, K: ?Sized, V: ?Sized> { + pub raw: RawMap, + pub arena: &'msg Arena, + pub _phantom_key: PhantomData<&'msg mut K>, + pub _phantom_value: PhantomData<&'msg mut V>, +} + +impl<'msg, K: ?Sized, V: ?Sized> Copy for MapInner<'msg, K, V> {} +impl<'msg, K: ?Sized, V: ?Sized> Clone for MapInner<'msg, K, V> { + fn clone(&self) -> MapInner<'msg, K, V> { + *self + } +} + +macro_rules! generate_map_key_ops_traits { + ($($t:ty, $sized_t:ty;)*) => { + paste! { + $( + pub trait [< MapWith $t:camel KeyOps >] { + type Value<'msg>: Sized; + + fn new_map(a: RawArena) -> RawMap; + fn clear(m: RawMap) { + unsafe { upb_Map_Clear(m) } + } + fn size(m: RawMap) -> usize { + unsafe { upb_Map_Size(m) } + } + fn insert(m: RawMap, a: RawArena, key: $sized_t, value: Self::Value<'_>) -> bool; + fn get<'msg>(m: RawMap, key: $sized_t) -> Option>; + fn remove(m: RawMap, key: $sized_t) -> bool; + } + + impl<'msg, V: [< MapWith $t:camel KeyOps >] + ?Sized> MapInner<'msg, $t, V> { + + pub fn new(arena: &'msg mut Arena) -> Self { + MapInner { + raw: V::new_map(arena.raw()), + arena, + _phantom_key: PhantomData, + _phantom_value: PhantomData + } + } + + pub fn size(&self) -> usize { + V::size(self.raw) + } + + pub fn clear(&mut self) { + V::clear(self.raw) + } + + pub fn get<'a>(&self, key: $sized_t) -> Option> { + V::get(self.raw, key) + } + + pub fn remove(&mut self, key: $sized_t) -> bool { + V::remove(self.raw, key) + } + + pub fn insert(&mut self, key: $sized_t, value: V::Value<'_>) -> bool { + V::insert(self.raw, self.arena.raw(), key, value) + } + } + )* + } + } +} + +generate_map_key_ops_traits!( + i32, i32; + u32, u32; + i64, i64; + u64, u64; + bool, bool; + ProtoStr, &ProtoStr; +); + +macro_rules! impl_scalar_map_key_op_for_scalar_values { + ($key_t:ty, $key_msg_val:expr, $key_upb_tag:expr, $trait:ident for $($t:ty, $sized_t:ty, $msg_val:expr, $from_msg_val:expr, $upb_tag:expr, $zero_val:literal;)*) => { + $( + impl $trait for $t { + type Value<'msg> = $sized_t; + + fn new_map(a: RawArena) -> RawMap { + unsafe { upb_Map_New(a, $key_upb_tag, $upb_tag) } + } + + fn insert(m: RawMap, a: RawArena, key: $key_t, value: Self::Value<'_>) -> bool { + unsafe { + upb_Map_Set( + m, + $key_msg_val(key), + $msg_val(value), + a + ) + } + } + + fn get<'msg>(m: RawMap, key: $key_t) -> Option> { + let mut val = $msg_val($zero_val); + let found = unsafe { + upb_Map_Get(m, $key_msg_val(key), &mut val) + }; + if !found { + return None; + } + Some($from_msg_val(val)) + } + + fn remove(m: RawMap, key: $key_t) -> bool { + let mut val = $msg_val($zero_val); + unsafe { + upb_Map_Delete(m, $key_msg_val(key), &mut val) + } + } + } + )* + } +} + +macro_rules! scalar_to_msg { + ($ufield:ident) => { + |val| upb_MessageValue { $ufield: val } + }; +} + +macro_rules! scalar_from_msg { + ($ufield:ident) => { + |msg: upb_MessageValue| unsafe { msg.$ufield } + }; +} + +fn str_to_msg<'msg>(val: impl Into<&'msg ProtoStr>) -> upb_MessageValue { + upb_MessageValue { str_val: val.into().as_bytes().into() } +} + +fn msg_to_str<'msg>(msg: upb_MessageValue) -> &'msg ProtoStr { + unsafe { ProtoStr::from_utf8_unchecked(msg.str_val.as_ref()) } +} + +macro_rules! impl_map_key_ops_for_scalar_values { + ($($t:ty, $t_sized:ty, $key_msg_val:expr, $upb_tag:expr;)*) => { + paste! { + $( + impl_scalar_map_key_op_for_scalar_values!($t_sized, $key_msg_val, $upb_tag, [< MapWith $t:camel KeyOps >] for + f32, f32, scalar_to_msg!(float_val), scalar_from_msg!(float_val), UpbCType::Float, 0f32; + f64, f64, scalar_to_msg!(double_val), scalar_from_msg!(double_val), UpbCType::Double, 0f64; + i32, i32, scalar_to_msg!(int32_val), scalar_from_msg!(int32_val), UpbCType::Int32, 0i32; + u32, u32, scalar_to_msg!(uint32_val), scalar_from_msg!(uint32_val), UpbCType::UInt32, 0u32; + i64, i64, scalar_to_msg!(int64_val), scalar_from_msg!(int64_val), UpbCType::Int64, 0i64; + u64, u64, scalar_to_msg!(uint64_val), scalar_from_msg!(uint64_val), UpbCType::UInt64, 0u64; + bool, bool, scalar_to_msg!(bool_val), scalar_from_msg!(bool_val), UpbCType::Bool, false; + ProtoStr, &'msg ProtoStr, str_to_msg, msg_to_str, UpbCType::String, ""; + ); + )* + } + } +} + +impl_map_key_ops_for_scalar_values!( + i32, i32, scalar_to_msg!(int32_val), UpbCType::Int32; + u32, u32, scalar_to_msg!(uint32_val), UpbCType::UInt32; + i64, i64, scalar_to_msg!(int64_val), UpbCType::Int64; + u64, u64, scalar_to_msg!(uint64_val), UpbCType::UInt64; + bool, bool, scalar_to_msg!(bool_val), UpbCType::Bool; + ProtoStr, &ProtoStr, |val: &ProtoStr| upb_MessageValue { str_val: val.as_bytes().into() }, UpbCType::String; +); + +extern "C" { + fn upb_Map_New(arena: RawArena, key_type: UpbCType, value_type: UpbCType) -> RawMap; + fn upb_Map_Size(map: RawMap) -> usize; + fn upb_Map_Set( + map: RawMap, + key: upb_MessageValue, + value: upb_MessageValue, + arena: RawArena, + ) -> bool; + fn upb_Map_Get(map: RawMap, key: upb_MessageValue, value: *mut upb_MessageValue) -> bool; + fn upb_Map_Delete( + map: RawMap, + key: upb_MessageValue, + removed_value: *mut upb_MessageValue, + ) -> bool; + fn upb_Map_Clear(map: RawMap); +} + +#[cfg(test)] +pub(crate) fn new_map_i32_i64() -> MapInner<'static, i32, i64> { + let arena = Box::leak::<'static>(Box::new(Arena::new())); + MapInner::<'static, i32, i64>::new(arena) +} + +#[cfg(test)] +pub(crate) fn new_map_str_str() -> MapInner<'static, ProtoStr, ProtoStr> { + let arena = Box::leak::<'static>(Box::new(Arena::new())); + MapInner::<'static, ProtoStr, ProtoStr>::new(arena) +} + #[cfg(test)] mod tests { use super::*; + use googletest::prelude::*; #[test] fn test_arena_new_and_free() { @@ -474,37 +719,129 @@ mod tests { len, ) }; - assert_eq!(&*serialized_data, b"Hello world"); + assert_that!(&*serialized_data, eq(b"Hello world")); } #[test] fn i32_array() { let arena = Arena::new(); let mut arr = RepeatedField::::new(&arena); - assert_eq!(arr.len(), 0); + assert_that!(arr.len(), eq(0)); arr.push(1); - assert_eq!(arr.get(0), Some(1)); - assert_eq!(arr.len(), 1); + assert_that!(arr.get(0), eq(Some(1))); + assert_that!(arr.len(), eq(1)); arr.set(0, 3); - assert_eq!(arr.get(0), Some(3)); + assert_that!(arr.get(0), eq(Some(3))); for i in 0..2048 { arr.push(i); - assert_eq!(arr.get(arr.len() - 1), Some(i)); + assert_that!(arr.get(arr.len() - 1), eq(Some(i))); } } #[test] fn u32_array() { let mut arena = Arena::new(); let mut arr = RepeatedField::::new(&mut arena); - assert_eq!(arr.len(), 0); + assert_that!(arr.len(), eq(0)); arr.push(1); - assert_eq!(arr.get(0), Some(1)); - assert_eq!(arr.len(), 1); + assert_that!(arr.get(0), eq(Some(1))); + assert_that!(arr.len(), eq(1)); arr.set(0, 3); - assert_eq!(arr.get(0), Some(3)); + assert_that!(arr.get(0), eq(Some(3))); for i in 0..2048 { arr.push(i); - assert_eq!(arr.get(arr.len() - 1), Some(i)); + assert_that!(arr.get(arr.len() - 1), eq(Some(i))); } } + + #[test] + fn i32_i32_map() { + let mut arena = Arena::new(); + let mut map = MapInner::<'_, i32, i32>::new(&mut arena); + assert_that!(map.size(), eq(0)); + + assert_that!(map.insert(1, 2), eq(true)); + assert_that!(map.get(1), eq(Some(2))); + assert_that!(map.get(3), eq(None)); + assert_that!(map.size(), eq(1)); + + assert_that!(map.remove(1), eq(true)); + assert_that!(map.size(), eq(0)); + assert_that!(map.remove(1), eq(false)); + + assert_that!(map.insert(4, 5), eq(true)); + assert_that!(map.insert(6, 7), eq(true)); + map.clear(); + assert_that!(map.size(), eq(0)); + } + + #[test] + fn i64_f64_map() { + let mut arena = Arena::new(); + let mut map = MapInner::<'_, i64, f64>::new(&mut arena); + assert_that!(map.size(), eq(0)); + + assert_that!(map.insert(1, 2.5), eq(true)); + assert_that!(map.get(1), eq(Some(2.5))); + assert_that!(map.get(3), eq(None)); + assert_that!(map.size(), eq(1)); + + assert_that!(map.remove(1), eq(true)); + assert_that!(map.size(), eq(0)); + assert_that!(map.remove(1), eq(false)); + + assert_that!(map.insert(4, 5.1), eq(true)); + assert_that!(map.insert(6, 7.2), eq(true)); + map.clear(); + assert_that!(map.size(), eq(0)); + } + + #[test] + fn str_str_map() { + let mut arena = Arena::new(); + let mut map = MapInner::<'_, ProtoStr, ProtoStr>::new(&mut arena); + assert_that!(map.size(), eq(0)); + + map.insert("fizz".into(), "buzz".into()); + assert_that!(map.size(), eq(1)); + assert_that!(map.remove("fizz".into()), eq(true)); + map.clear(); + assert_that!(map.size(), eq(0)); + } + + #[test] + fn u64_str_map() { + let mut arena = Arena::new(); + let mut map = MapInner::<'_, u64, ProtoStr>::new(&mut arena); + assert_that!(map.size(), eq(0)); + + map.insert(1, "fizz".into()); + map.insert(2, "buzz".into()); + assert_that!(map.size(), eq(2)); + assert_that!(map.remove(1), eq(true)); + map.clear(); + assert_that!(map.size(), eq(0)); + } + + #[test] + fn test_all_maps_can_be_constructed() { + macro_rules! gen_proto_values { + ($key_t:ty, $($value_t:ty),*) => { + let mut arena = Arena::new(); + $( + let map = MapInner::<'_, $key_t, $value_t>::new(&mut arena); + assert_that!(map.size(), eq(0)); + )* + } + } + + macro_rules! gen_proto_keys { + ($($key_t:ty),*) => { + $( + gen_proto_values!($key_t, f32, f64, i32, u32, i64, bool, ProtoStr); + )* + } + } + + gen_proto_keys!(i32, u32, i64, u64, bool, ProtoStr); + } } diff --git a/rust/upb_kernel/BUILD b/rust/upb_kernel/BUILD index b06f182117..3c373323e0 100644 --- a/rust/upb_kernel/BUILD +++ b/rust/upb_kernel/BUILD @@ -8,7 +8,7 @@ cc_library( "//rust:__subpackages__", ], deps = [ - "//upb:collections", "//upb:mem", + "//upb:message", ], ) diff --git a/rust/upb_kernel/upb_api.c b/rust/upb_kernel/upb_api.c index a30b4dd9bb..7de8d0bd4d 100644 --- a/rust/upb_kernel/upb_api.c +++ b/rust/upb_kernel/upb_api.c @@ -8,5 +8,6 @@ #define UPB_BUILD_API -#include "upb/collections/array.h" // IWYU pragma: keep -#include "upb/mem/arena.h" // IWYU pragma: keep +#include "upb/mem/arena.h" // IWYU pragma: keep +#include "upb/message/array.h" // IWYU pragma: keep +#include "upb/message/map.h" // IWYU pragma: keep diff --git a/src/file_lists.cmake b/src/file_lists.cmake index e4718cf8a3..679cb83df0 100644 --- a/src/file_lists.cmake +++ b/src/file_lists.cmake @@ -116,7 +116,7 @@ set(libprotobuf_hdrs ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor.h ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor.pb.h ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_database.h - ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_legacy.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_lite.h ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_visitor.h ${protobuf_SOURCE_DIR}/src/google/protobuf/dynamic_message.h ${protobuf_SOURCE_DIR}/src/google/protobuf/endian.h @@ -242,6 +242,7 @@ set(libprotobuf_lite_hdrs ${protobuf_SOURCE_DIR}/src/google/protobuf/arena_cleanup.h ${protobuf_SOURCE_DIR}/src/google/protobuf/arenastring.h ${protobuf_SOURCE_DIR}/src/google/protobuf/arenaz_sampler.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_lite.h ${protobuf_SOURCE_DIR}/src/google/protobuf/endian.h ${protobuf_SOURCE_DIR}/src/google/protobuf/explicitly_constructed.h ${protobuf_SOURCE_DIR}/src/google/protobuf/extension_set.h @@ -285,10 +286,8 @@ set(libprotobuf_lite_hdrs # @//pkg:protoc set(libprotoc_srcs - ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/allowlists/editions.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/allowlists/empty_package.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/allowlists/open_enum.cc - ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/allowlists/unused_imports.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/code_generator.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/command_line_interface.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/cpp/enum.cc @@ -383,6 +382,8 @@ set(libprotoc_srcs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/retention.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/ruby/ruby_generator.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/accessors/accessors.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/accessors/helpers.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/accessors/map.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/accessors/repeated_scalar.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/accessors/singular_message.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc @@ -395,6 +396,7 @@ set(libprotoc_srcs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/oneof.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/relative_path.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/subprocess.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/versions.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/zip_writer.cc ) @@ -499,6 +501,7 @@ set(libprotoc_hdrs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/ruby/ruby_generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/accessors/accessor_generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/accessors/accessors.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/accessors/helpers.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/context.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/rust/message.h @@ -508,7 +511,6 @@ set(libprotoc_hdrs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/scc.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/subprocess.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/versions.h - ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/versions_suffix.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/zip_writer.h ) @@ -647,6 +649,7 @@ set(test_util_srcs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/annotation_test_util.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/reflection_tester.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/test_util.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/unredacted_debug_format_for_test.cc ) # @//pkg:test_util @@ -662,6 +665,7 @@ set(test_util_hdrs ${protobuf_SOURCE_DIR}/src/google/protobuf/reflection_tester.h ${protobuf_SOURCE_DIR}/src/google/protobuf/test_util.h ${protobuf_SOURCE_DIR}/src/google/protobuf/test_util.inc + ${protobuf_SOURCE_DIR}/src/google/protobuf/unredacted_debug_format_for_test.h ${protobuf_SOURCE_DIR}/src/google/protobuf/wire_format_unittest.inc ) @@ -704,6 +708,8 @@ set(protobuf_test_files ${protobuf_SOURCE_DIR}/src/google/protobuf/string_block_test.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/text_format_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/unknown_field_set_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/unredacted_debug_format_for_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/unredacted_debug_format_for_test_test.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/varint_shuffle_test.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/well_known_types_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/wire_format_unittest.cc @@ -791,9 +797,11 @@ set(compiler_test_files ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/names_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/text_format_decode_data_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/parser_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/php/generator_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/plugin_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/retention_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/versions_test.cc ) # @//src/google/protobuf/compiler:test_proto_srcs diff --git a/src/google/protobuf/BUILD.bazel b/src/google/protobuf/BUILD.bazel index f85e88b16c..1177d9e99d 100644 --- a/src/google/protobuf/BUILD.bazel +++ b/src/google/protobuf/BUILD.bazel @@ -239,6 +239,7 @@ cc_test( deps = [ ":port_def", ":varint_shuffle", + "@com_google_absl//absl/base:config", "@com_google_absl//absl/log:absl_check", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", @@ -337,6 +338,7 @@ cc_library( "@com_google_absl//absl/log:absl_check", "@com_google_absl//absl/log:absl_log", "@com_google_absl//absl/synchronization", + "@com_google_absl//absl/utility:if_constexpr", ], ) @@ -389,6 +391,7 @@ cc_library( "arena.h", "arenastring.h", "arenaz_sampler.h", + "descriptor_lite.h", "endian.h", "explicitly_constructed.h", "extension_set.h", @@ -436,7 +439,9 @@ cc_library( ":varint_shuffle", "//src/google/protobuf/io", "//src/google/protobuf/stubs:lite", + "//third_party/utf8_range:utf8_validity", "@com_google_absl//absl/base", + "@com_google_absl//absl/base:config", "@com_google_absl//absl/container:btree", "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/hash", @@ -447,7 +452,6 @@ cc_library( "@com_google_absl//absl/strings:internal", "@com_google_absl//absl/synchronization", "@com_google_absl//absl/time", - "@utf8_range//:utf8_validity", ], ) @@ -482,7 +486,6 @@ cc_library( "descriptor.h", "descriptor.pb.h", "descriptor_database.h", - "descriptor_legacy.h", "descriptor_visitor.h", "dynamic_message.h", "feature_resolver.h", @@ -521,6 +524,7 @@ cc_library( "//src/google/protobuf/io:printer", "//src/google/protobuf/io:tokenizer", "//src/google/protobuf/stubs", + "//third_party/utf8_range:utf8_validity", "@com_google_absl//absl/base", "@com_google_absl//absl/base:dynamic_annotations", "@com_google_absl//absl/container:btree", @@ -532,7 +536,6 @@ cc_library( "@com_google_absl//absl/strings:internal", "@com_google_absl//absl/synchronization", "@com_google_absl//absl/time", - "@utf8_range//:utf8_validity", ], ) @@ -577,20 +580,6 @@ cc_library( strip_include_prefix = "/src", ) -cc_library( - name = "descriptor_legacy", - hdrs = ["descriptor_legacy.h"], - copts = COPTS, - linkopts = LINK_OPTS, - strip_include_prefix = "/src", - visibility = ["//:__subpackages__"], - deps = [ - ":port_def", - ":protobuf_nowkt", - "@com_google_absl//absl/strings", - ], -) - cc_library( name = "descriptor_visitor", hdrs = ["descriptor_visitor.h"], @@ -795,6 +784,7 @@ exports_files( visibility = [ "//:__pkg__", "//python:__pkg__", + "//ruby:__pkg__", ], ) @@ -886,6 +876,7 @@ cc_library( visibility = ["//:__subpackages__"], deps = [ ":cc_lite_test_protos", + ":port_def", ":test_util2", "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/log:absl_check", @@ -1038,7 +1029,6 @@ cc_test( }), deps = [ ":cc_test_protos", - ":descriptor_legacy", ":protobuf", ":test_textproto", "//src/google/protobuf/compiler:importer", @@ -1334,7 +1324,6 @@ cc_test( }), deps = [ ":cc_test_protos", - ":descriptor_legacy", ":protobuf", ":test_util", "//src/google/protobuf/stubs", @@ -1423,6 +1412,7 @@ cc_test( "//src/google/protobuf/io", "//src/google/protobuf/stubs", "//src/google/protobuf/testing", + "@com_google_absl//absl/random", "@com_google_absl//absl/types:span", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", @@ -1563,6 +1553,30 @@ cc_test( ], ) +cc_library( + name = "unredacted_debug_format_for_test", + testonly = True, + srcs = ["unredacted_debug_format_for_test.cc"], + hdrs = ["unredacted_debug_format_for_test.h"], + strip_include_prefix = "/src", + visibility = ["//visibility:public"], + deps = [ + ":protobuf", + ], +) + +cc_test( + name = "unredacted_debug_format_for_test_test", + srcs = ["unredacted_debug_format_for_test_test.cc"], + deps = [ + ":cc_lite_test_protos", + ":cc_test_protos", + ":protobuf", + ":unredacted_debug_format_for_test", + "@com_google_googletest//:gtest_main", + ], +) + ################################################################################ # Helper targets for Kotlin tests ################################################################################ diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc index 429b41c6f8..47ebf5bd43 100644 --- a/src/google/protobuf/any.pb.cc +++ b/src/google/protobuf/any.pb.cc @@ -1,5 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/any.proto +// Protobuf C++ Version: 4.26.0-dev #include "google/protobuf/any.pb.h" @@ -123,9 +124,6 @@ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fany_2eproto = PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fany_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2fany_2eproto; } -// Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 -static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fany_2eproto(&descriptor_table_google_2fprotobuf_2fany_2eproto); namespace google { namespace protobuf { // =================================================================== @@ -198,12 +196,13 @@ inline void Any::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* Any::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { Any::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(Any, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void Any::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Any) @@ -238,6 +237,9 @@ const ::_pbi::TcParseTable<1, 2, 0, 36, 2> Any::_table_ = { offsetof(decltype(_table_), field_names), // no aux_entries &_Any_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::Any>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // bytes value = 2; {::_pbi::TcParser::FastBS1, @@ -317,7 +319,7 @@ const ::_pbi::TcParseTable<1, 2, 0, 36, 2> Any::_table_ = { } -void Any::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void Any::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Any) @@ -345,9 +347,6 @@ PROTOBUF_NOINLINE bool Any::IsInitialized() const { return true; } -::_pbi::CachedSize* Any::AccessCachedSize() const { - return &_impl_._cached_size_; -} void Any::InternalSwap(Any* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -358,9 +357,9 @@ void Any::InternalSwap(Any* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata Any::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fany_2eproto_getter, &descriptor_table_google_2fprotobuf_2fany_2eproto_once, - file_level_metadata_google_2fprotobuf_2fany_2eproto[0]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fany_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fany_2eproto_once, + file_level_metadata_google_2fprotobuf_2fany_2eproto[0]); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf @@ -373,4 +372,8 @@ namespace protobuf { #if defined(__llvm__) #pragma clang diagnostic pop #endif // __llvm__ +PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 +static ::std::false_type _static_init_ PROTOBUF_UNUSED = + (::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2fany_2eproto), + ::std::false_type{}); #include "google/protobuf/port_undef.inc" diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index f6eecf8cd5..2595f04be6 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h @@ -1,6 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/any.proto -// Protobuf C++ Version: 4.24.0-main +// Protobuf C++ Version: 4.26.0-dev #ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto_2epb_2eh #define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fany_2eproto_2epb_2eh @@ -11,17 +11,11 @@ #include #include "google/protobuf/port_def.inc" -#if PROTOBUF_VERSION < 4024000 -#error "This file was generated by a newer version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please update" -#error "your headers." -#endif // PROTOBUF_VERSION - -#if 4024000 < PROTOBUF_MIN_PROTOC_VERSION -#error "This file was generated by an older version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please" -#error "regenerate this file with a newer version of protoc." -#endif // PROTOBUF_MIN_PROTOC_VERSION +#if PROTOBUF_VERSION != 4026000 +#error "Protobuf C++ gencode is built with an incompatible version of" +#error "Protobuf C++ headers/runtime. See" +#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp" +#endif #include "google/protobuf/port_undef.inc" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/arena.h" @@ -71,21 +65,18 @@ namespace protobuf { // ------------------------------------------------------------------- -class PROTOBUF_EXPORT Any final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Any) */ { +class PROTOBUF_EXPORT Any final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.Any) */ { public: inline Any() : Any(nullptr) {} ~Any() override; - template - explicit PROTOBUF_CONSTEXPR Any(::google::protobuf::internal::ConstantInitialized); - - inline Any(const Any& from) - : Any(nullptr, from) {} - Any(Any&& from) noexcept - : Any() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR Any( + ::google::protobuf::internal::ConstantInitialized); + inline Any(const Any& from) : Any(nullptr, from) {} + inline Any(Any&& from) noexcept + : Any(nullptr, std::move(from)) {} inline Any& operator=(const Any& from) { CopyFrom(from); return *this; @@ -93,9 +84,9 @@ class PROTOBUF_EXPORT Any final : inline Any& operator=(Any&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -127,12 +118,11 @@ class PROTOBUF_EXPORT Any final : } static inline const Any* internal_default_instance() { return reinterpret_cast( - &_Any_default_instance_); + &_Any_default_instance_); } - static constexpr int kIndexInFileMessages = - 0; - - // implements Any ----------------------------------------------- + static constexpr int kIndexInFileMessages = 0; + // implements Any + // ----------------------------------------------- bool PackFrom(const ::google::protobuf::Message& message) { ABSL_DCHECK_NE(&message, this); @@ -150,34 +140,43 @@ class PROTOBUF_EXPORT Any final : const ::google::protobuf::Message& message, const ::google::protobuf::FieldDescriptor** type_url_field, const ::google::protobuf::FieldDescriptor** value_field); - template ::value>::type> + template < + typename T, + class = typename std::enable_if::value>::type> bool PackFrom(const T& message) { return _impl_._any_metadata_.PackFrom(GetArena(), message); } - template ::value>::type> + template < + typename T, + class = typename std::enable_if::value>::type> bool PackFrom(const T& message, ::absl::string_view type_url_prefix) { - return _impl_._any_metadata_.PackFrom(GetArena(), message, type_url_prefix);} - template ::value>::type> + return _impl_._any_metadata_.PackFrom(GetArena(), message, type_url_prefix); + } + template < + typename T, + class = typename std::enable_if::value>::type> bool UnpackTo(T* message) const { return _impl_._any_metadata_.UnpackTo(message); } - template bool Is() const { + + template + bool Is() const { return _impl_._any_metadata_.Is(); } static bool ParseAnyTypeUrl(::absl::string_view type_url, std::string* full_type_name); - friend void swap(Any& a, Any& b) { - a.Swap(&b); - } + friend void swap(Any& a, Any& b) { a.Swap(&b); } inline void Swap(Any* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -192,16 +191,18 @@ class PROTOBUF_EXPORT Any final : // implements Message ---------------------------------------------- Any* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const Any& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const Any& from) { - Any::MergeImpl(*this, from); - } + void MergeFrom(const Any& from) { Any::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -209,32 +210,33 @@ class PROTOBUF_EXPORT Any final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(Any* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.Any"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.Any"; } + + protected: explicit Any(::google::protobuf::Arena* arena); Any(::google::protobuf::Arena* arena, const Any& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + Any(::google::protobuf::Arena* arena, Any&& from) noexcept + : Any(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kTypeUrlFieldNumber = 1, kValueFieldNumber = 2, @@ -274,7 +276,6 @@ class PROTOBUF_EXPORT Any final : // @@protoc_insertion_point(class_scope:google.protobuf.Any) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 1, 2, 0, @@ -286,14 +287,13 @@ class PROTOBUF_EXPORT Any final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::ArenaStringPtr type_url_; ::google::protobuf::internal::ArenaStringPtr value_; mutable ::google::protobuf::internal::CachedSize _cached_size_; @@ -334,7 +334,6 @@ template inline PROTOBUF_ALWAYS_INLINE void Any::set_type_url(Arg_&& arg, Args_... args) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.type_url_.Set(static_cast(arg), args..., GetArena()); // @@protoc_insertion_point(field_set:google.protobuf.Any.type_url) } @@ -349,12 +348,10 @@ inline const std::string& Any::_internal_type_url() const { } inline void Any::_internal_set_type_url(const std::string& value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.type_url_.Set(value, GetArena()); } inline std::string* Any::_internal_mutable_type_url() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; return _impl_.type_url_.Mutable( GetArena()); } inline std::string* Any::release_type_url() { @@ -387,7 +384,6 @@ template inline PROTOBUF_ALWAYS_INLINE void Any::set_value(Arg_&& arg, Args_... args) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.value_.SetBytes(static_cast(arg), args..., GetArena()); // @@protoc_insertion_point(field_set:google.protobuf.Any.value) } @@ -402,12 +398,10 @@ inline const std::string& Any::_internal_value() const { } inline void Any::_internal_set_value(const std::string& value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.value_.Set(value, GetArena()); } inline std::string* Any::_internal_mutable_value() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; return _impl_.value_.Mutable( GetArena()); } inline std::string* Any::release_value() { diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index 773786a15b..915f05a5ec 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc @@ -1,5 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/api.proto +// Protobuf C++ Version: 4.26.0-dev #include "google/protobuf/api.pb.h" @@ -237,9 +238,6 @@ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fapi_2eproto = PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fapi_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2fapi_2eproto; } -// Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 -static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fapi_2eproto(&descriptor_table_google_2fprotobuf_2fapi_2eproto); namespace google { namespace protobuf { // =================================================================== @@ -249,15 +247,8 @@ class Api::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(Api, _impl_._has_bits_); - static const ::google::protobuf::SourceContext& source_context(const Api* msg); - static void set_has_source_context(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } }; -const ::google::protobuf::SourceContext& Api::_Internal::source_context(const Api* msg) { - return *msg->_impl_.source_context_; -} void Api::clear_options() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); _impl_.options_.Clear(); @@ -293,9 +284,9 @@ Api::Api( from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.source_context_ = (cached_has_bits & 0x00000001u) - ? CreateMaybeMessage<::google::protobuf::SourceContext>(arena, *from._impl_.source_context_) - : nullptr; + _impl_.source_context_ = (cached_has_bits & 0x00000001u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::SourceContext>( + arena, *from._impl_.source_context_) + : nullptr; _impl_.syntax_ = from._impl_.syntax_; // @@protoc_insertion_point(copy_constructor:google.protobuf.Api) @@ -335,12 +326,13 @@ inline void Api::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* Api::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { Api::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(Api, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void Api::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Api) @@ -385,6 +377,9 @@ const ::_pbi::TcParseTable<3, 7, 4, 39, 2> Api::_table_ = { offsetof(decltype(_table_), aux_entries), &_Api_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::Api>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // string name = 1; @@ -488,8 +483,7 @@ const ::_pbi::TcParseTable<3, 7, 4, 39, 2> Api::_table_ = { // .google.protobuf.SourceContext source_context = 5; if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 5, _Internal::source_context(this), - _Internal::source_context(this).GetCachedSize(), target, stream); + 5, *_impl_.source_context_, _impl_.source_context_->GetCachedSize(), target, stream); } // repeated .google.protobuf.Mixin mixins = 6; @@ -571,9 +565,10 @@ const ::_pbi::TcParseTable<3, 7, 4, 39, 2> Api::_table_ = { } -void Api::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void Api::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Api) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -591,13 +586,20 @@ void Api::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobu if (!from._internal_version().empty()) { _this->_internal_set_version(from._internal_version()); } - if ((from._impl_._has_bits_[0] & 0x00000001u) != 0) { - _this->_internal_mutable_source_context()->::google::protobuf::SourceContext::MergeFrom( - from._internal_source_context()); + cached_has_bits = from._impl_._has_bits_[0]; + if (cached_has_bits & 0x00000001u) { + ABSL_DCHECK(from._impl_.source_context_ != nullptr); + if (_this->_impl_.source_context_ == nullptr) { + _this->_impl_.source_context_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::SourceContext>(arena, *from._impl_.source_context_); + } else { + _this->_impl_.source_context_->MergeFrom(*from._impl_.source_context_); + } } if (from._internal_syntax() != 0) { - _this->_internal_set_syntax(from._internal_syntax()); + _this->_impl_.syntax_ = from._impl_.syntax_; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -612,9 +614,6 @@ PROTOBUF_NOINLINE bool Api::IsInitialized() const { return true; } -::_pbi::CachedSize* Api::AccessCachedSize() const { - return &_impl_._cached_size_; -} void Api::InternalSwap(Api* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -635,9 +634,9 @@ void Api::InternalSwap(Api* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata Api::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, - file_level_metadata_google_2fprotobuf_2fapi_2eproto[0]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, + file_level_metadata_google_2fprotobuf_2fapi_2eproto[0]); } // =================================================================== @@ -716,12 +715,13 @@ inline void Method::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* Method::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { Method::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(Method, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void Method::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Method) @@ -761,6 +761,9 @@ const ::_pbi::TcParseTable<3, 7, 1, 68, 2> Method::_table_ = { offsetof(decltype(_table_), aux_entries), &_Method_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::Method>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // string name = 1; @@ -940,7 +943,7 @@ const ::_pbi::TcParseTable<3, 7, 1, 68, 2> Method::_table_ = { } -void Method::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void Method::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Method) @@ -960,13 +963,13 @@ void Method::MergeImpl(::google::protobuf::Message& to_msg, const ::google::prot _this->_internal_set_response_type_url(from._internal_response_type_url()); } if (from._internal_request_streaming() != 0) { - _this->_internal_set_request_streaming(from._internal_request_streaming()); + _this->_impl_.request_streaming_ = from._impl_.request_streaming_; } if (from._internal_response_streaming() != 0) { - _this->_internal_set_response_streaming(from._internal_response_streaming()); + _this->_impl_.response_streaming_ = from._impl_.response_streaming_; } if (from._internal_syntax() != 0) { - _this->_internal_set_syntax(from._internal_syntax()); + _this->_impl_.syntax_ = from._impl_.syntax_; } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -982,9 +985,6 @@ PROTOBUF_NOINLINE bool Method::IsInitialized() const { return true; } -::_pbi::CachedSize* Method::AccessCachedSize() const { - return &_impl_._cached_size_; -} void Method::InternalSwap(Method* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -1003,9 +1003,9 @@ void Method::InternalSwap(Method* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata Method::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, - file_level_metadata_google_2fprotobuf_2fapi_2eproto[1]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, + file_level_metadata_google_2fprotobuf_2fapi_2eproto[1]); } // =================================================================== @@ -1062,12 +1062,13 @@ inline void Mixin::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* Mixin::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { Mixin::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(Mixin, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void Mixin::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Mixin) @@ -1102,6 +1103,9 @@ const ::_pbi::TcParseTable<1, 2, 0, 38, 2> Mixin::_table_ = { offsetof(decltype(_table_), field_names), // no aux_entries &_Mixin_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::Mixin>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // string root = 2; {::_pbi::TcParser::FastUS1, @@ -1184,7 +1188,7 @@ const ::_pbi::TcParseTable<1, 2, 0, 38, 2> Mixin::_table_ = { } -void Mixin::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void Mixin::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Mixin) @@ -1212,9 +1216,6 @@ PROTOBUF_NOINLINE bool Mixin::IsInitialized() const { return true; } -::_pbi::CachedSize* Mixin::AccessCachedSize() const { - return &_impl_._cached_size_; -} void Mixin::InternalSwap(Mixin* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -1225,9 +1226,9 @@ void Mixin::InternalSwap(Mixin* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata Mixin::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, - file_level_metadata_google_2fprotobuf_2fapi_2eproto[2]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fapi_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fapi_2eproto_once, + file_level_metadata_google_2fprotobuf_2fapi_2eproto[2]); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf @@ -1237,4 +1238,8 @@ namespace protobuf { } // namespace protobuf } // namespace google // @@protoc_insertion_point(global_scope) +PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 +static ::std::false_type _static_init_ PROTOBUF_UNUSED = + (::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2fapi_2eproto), + ::std::false_type{}); #include "google/protobuf/port_undef.inc" diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h index 08d2f8addf..fbaa6c583a 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h @@ -1,6 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/api.proto -// Protobuf C++ Version: 4.24.0-main +// Protobuf C++ Version: 4.26.0-dev #ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto_2epb_2eh #define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fapi_2eproto_2epb_2eh @@ -11,17 +11,11 @@ #include #include "google/protobuf/port_def.inc" -#if PROTOBUF_VERSION < 4024000 -#error "This file was generated by a newer version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please update" -#error "your headers." -#endif // PROTOBUF_VERSION - -#if 4024000 < PROTOBUF_MIN_PROTOC_VERSION -#error "This file was generated by an older version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please" -#error "regenerate this file with a newer version of protoc." -#endif // PROTOBUF_MIN_PROTOC_VERSION +#if PROTOBUF_VERSION != 4026000 +#error "Protobuf C++ gencode is built with an incompatible version of" +#error "Protobuf C++ headers/runtime. See" +#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp" +#endif #include "google/protobuf/port_undef.inc" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/arena.h" @@ -79,21 +73,18 @@ namespace protobuf { // ------------------------------------------------------------------- -class PROTOBUF_EXPORT Mixin final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Mixin) */ { +class PROTOBUF_EXPORT Mixin final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.Mixin) */ { public: inline Mixin() : Mixin(nullptr) {} ~Mixin() override; - template - explicit PROTOBUF_CONSTEXPR Mixin(::google::protobuf::internal::ConstantInitialized); - - inline Mixin(const Mixin& from) - : Mixin(nullptr, from) {} - Mixin(Mixin&& from) noexcept - : Mixin() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR Mixin( + ::google::protobuf::internal::ConstantInitialized); + inline Mixin(const Mixin& from) : Mixin(nullptr, from) {} + inline Mixin(Mixin&& from) noexcept + : Mixin(nullptr, std::move(from)) {} inline Mixin& operator=(const Mixin& from) { CopyFrom(from); return *this; @@ -101,9 +92,9 @@ class PROTOBUF_EXPORT Mixin final : inline Mixin& operator=(Mixin&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -135,22 +126,17 @@ class PROTOBUF_EXPORT Mixin final : } static inline const Mixin* internal_default_instance() { return reinterpret_cast( - &_Mixin_default_instance_); - } - static constexpr int kIndexInFileMessages = - 2; - - friend void swap(Mixin& a, Mixin& b) { - a.Swap(&b); + &_Mixin_default_instance_); } + static constexpr int kIndexInFileMessages = 2; + friend void swap(Mixin& a, Mixin& b) { a.Swap(&b); } inline void Swap(Mixin* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -165,16 +151,18 @@ class PROTOBUF_EXPORT Mixin final : // implements Message ---------------------------------------------- Mixin* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const Mixin& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const Mixin& from) { - Mixin::MergeImpl(*this, from); - } + void MergeFrom(const Mixin& from) { Mixin::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -182,32 +170,33 @@ class PROTOBUF_EXPORT Mixin final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(Mixin* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.Mixin"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.Mixin"; } + + protected: explicit Mixin(::google::protobuf::Arena* arena); Mixin(::google::protobuf::Arena* arena, const Mixin& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + Mixin(::google::protobuf::Arena* arena, Mixin&& from) noexcept + : Mixin(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kNameFieldNumber = 1, kRootFieldNumber = 2, @@ -247,7 +236,6 @@ class PROTOBUF_EXPORT Mixin final : // @@protoc_insertion_point(class_scope:google.protobuf.Mixin) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 1, 2, 0, @@ -259,14 +247,13 @@ class PROTOBUF_EXPORT Mixin final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::ArenaStringPtr name_; ::google::protobuf::internal::ArenaStringPtr root_; mutable ::google::protobuf::internal::CachedSize _cached_size_; @@ -274,23 +261,21 @@ class PROTOBUF_EXPORT Mixin final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT Method final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Method) */ { +class PROTOBUF_EXPORT Method final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.Method) */ { public: inline Method() : Method(nullptr) {} ~Method() override; - template - explicit PROTOBUF_CONSTEXPR Method(::google::protobuf::internal::ConstantInitialized); - - inline Method(const Method& from) - : Method(nullptr, from) {} - Method(Method&& from) noexcept - : Method() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR Method( + ::google::protobuf::internal::ConstantInitialized); + inline Method(const Method& from) : Method(nullptr, from) {} + inline Method(Method&& from) noexcept + : Method(nullptr, std::move(from)) {} inline Method& operator=(const Method& from) { CopyFrom(from); return *this; @@ -298,9 +283,9 @@ class PROTOBUF_EXPORT Method final : inline Method& operator=(Method&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -332,22 +317,17 @@ class PROTOBUF_EXPORT Method final : } static inline const Method* internal_default_instance() { return reinterpret_cast( - &_Method_default_instance_); - } - static constexpr int kIndexInFileMessages = - 1; - - friend void swap(Method& a, Method& b) { - a.Swap(&b); + &_Method_default_instance_); } + static constexpr int kIndexInFileMessages = 1; + friend void swap(Method& a, Method& b) { a.Swap(&b); } inline void Swap(Method* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -362,16 +342,18 @@ class PROTOBUF_EXPORT Method final : // implements Message ---------------------------------------------- Method* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const Method& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const Method& from) { - Method::MergeImpl(*this, from); - } + void MergeFrom(const Method& from) { Method::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -379,32 +361,33 @@ class PROTOBUF_EXPORT Method final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(Method* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.Method"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.Method"; } + + protected: explicit Method(::google::protobuf::Arena* arena); Method(::google::protobuf::Arena* arena, const Method& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + Method(::google::protobuf::Arena* arena, Method&& from) noexcept + : Method(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kOptionsFieldNumber = 6, kNameFieldNumber = 1, @@ -422,16 +405,15 @@ class PROTOBUF_EXPORT Method final : public: void clear_options() ; ::google::protobuf::Option* mutable_options(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* - mutable_options(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>* mutable_options(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>& _internal_options() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>* _internal_mutable_options(); public: const ::google::protobuf::Option& options(int index) const; ::google::protobuf::Option* add_options(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& - options() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>& options() const; // string name = 1; void clear_name() ; const std::string& name() const; @@ -513,7 +495,6 @@ class PROTOBUF_EXPORT Method final : // @@protoc_insertion_point(class_scope:google.protobuf.Method) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 3, 7, 1, @@ -525,14 +506,13 @@ class PROTOBUF_EXPORT Method final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_; ::google::protobuf::internal::ArenaStringPtr name_; ::google::protobuf::internal::ArenaStringPtr request_type_url_; @@ -545,23 +525,21 @@ class PROTOBUF_EXPORT Method final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fapi_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT Api final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Api) */ { +class PROTOBUF_EXPORT Api final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.Api) */ { public: inline Api() : Api(nullptr) {} ~Api() override; - template - explicit PROTOBUF_CONSTEXPR Api(::google::protobuf::internal::ConstantInitialized); - - inline Api(const Api& from) - : Api(nullptr, from) {} - Api(Api&& from) noexcept - : Api() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR Api( + ::google::protobuf::internal::ConstantInitialized); + inline Api(const Api& from) : Api(nullptr, from) {} + inline Api(Api&& from) noexcept + : Api(nullptr, std::move(from)) {} inline Api& operator=(const Api& from) { CopyFrom(from); return *this; @@ -569,9 +547,9 @@ class PROTOBUF_EXPORT Api final : inline Api& operator=(Api&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -603,22 +581,17 @@ class PROTOBUF_EXPORT Api final : } static inline const Api* internal_default_instance() { return reinterpret_cast( - &_Api_default_instance_); - } - static constexpr int kIndexInFileMessages = - 0; - - friend void swap(Api& a, Api& b) { - a.Swap(&b); + &_Api_default_instance_); } + static constexpr int kIndexInFileMessages = 0; + friend void swap(Api& a, Api& b) { a.Swap(&b); } inline void Swap(Api* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -633,16 +606,18 @@ class PROTOBUF_EXPORT Api final : // implements Message ---------------------------------------------- Api* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const Api& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const Api& from) { - Api::MergeImpl(*this, from); - } + void MergeFrom(const Api& from) { Api::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -650,32 +625,33 @@ class PROTOBUF_EXPORT Api final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(Api* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.Api"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.Api"; } + + protected: explicit Api(::google::protobuf::Arena* arena); Api(::google::protobuf::Arena* arena, const Api& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + Api(::google::protobuf::Arena* arena, Api&& from) noexcept + : Api(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kMethodsFieldNumber = 2, kOptionsFieldNumber = 3, @@ -693,16 +669,15 @@ class PROTOBUF_EXPORT Api final : public: void clear_methods() ; ::google::protobuf::Method* mutable_methods(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >* - mutable_methods(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::Method>* mutable_methods(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::Method>& _internal_methods() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::Method>* _internal_mutable_methods(); public: const ::google::protobuf::Method& methods(int index) const; ::google::protobuf::Method* add_methods(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >& - methods() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::Method>& methods() const; // repeated .google.protobuf.Option options = 3; int options_size() const; private: @@ -711,16 +686,15 @@ class PROTOBUF_EXPORT Api final : public: void clear_options() ; ::google::protobuf::Option* mutable_options(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* - mutable_options(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>* mutable_options(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>& _internal_options() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>* _internal_mutable_options(); public: const ::google::protobuf::Option& options(int index) const; ::google::protobuf::Option* add_options(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& - options() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::Option>& options() const; // repeated .google.protobuf.Mixin mixins = 6; int mixins_size() const; private: @@ -729,16 +703,15 @@ class PROTOBUF_EXPORT Api final : public: void clear_mixins() ; ::google::protobuf::Mixin* mutable_mixins(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >* - mutable_mixins(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>* mutable_mixins(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>& _internal_mixins() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>* _internal_mutable_mixins(); public: const ::google::protobuf::Mixin& mixins(int index) const; ::google::protobuf::Mixin* add_mixins(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >& - mixins() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::Mixin>& mixins() const; // string name = 1; void clear_name() ; const std::string& name() const; @@ -799,7 +772,6 @@ class PROTOBUF_EXPORT Api final : // @@protoc_insertion_point(class_scope:google.protobuf.Api) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 3, 7, 4, @@ -811,14 +783,13 @@ class PROTOBUF_EXPORT Api final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method > methods_; @@ -864,7 +835,6 @@ template inline PROTOBUF_ALWAYS_INLINE void Api::set_name(Arg_&& arg, Args_... args) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.name_.Set(static_cast(arg), args..., GetArena()); // @@protoc_insertion_point(field_set:google.protobuf.Api.name) } @@ -879,12 +849,10 @@ inline const std::string& Api::_internal_name() const { } inline void Api::_internal_set_name(const std::string& value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.name_.Set(value, GetArena()); } inline std::string* Api::_internal_mutable_name() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; return _impl_.name_.Mutable( GetArena()); } inline std::string* Api::release_name() { @@ -1011,7 +979,6 @@ template inline PROTOBUF_ALWAYS_INLINE void Api::set_version(Arg_&& arg, Args_... args) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.version_.Set(static_cast(arg), args..., GetArena()); // @@protoc_insertion_point(field_set:google.protobuf.Api.version) } @@ -1026,12 +993,10 @@ inline const std::string& Api::_internal_version() const { } inline void Api::_internal_set_version(const std::string& value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.version_.Set(value, GetArena()); } inline std::string* Api::_internal_mutable_version() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; return _impl_.version_.Mutable( GetArena()); } inline std::string* Api::release_version() { @@ -1108,14 +1073,14 @@ inline ::google::protobuf::SourceContext* Api::unsafe_arena_release_source_conte } inline ::google::protobuf::SourceContext* Api::_internal_mutable_source_context() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000001u; if (_impl_.source_context_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::SourceContext>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::SourceContext>(GetArena()); _impl_.source_context_ = reinterpret_cast<::google::protobuf::SourceContext*>(p); } return _impl_.source_context_; } inline ::google::protobuf::SourceContext* Api::mutable_source_context() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000001u; ::google::protobuf::SourceContext* _msg = _internal_mutable_source_context(); // @@protoc_insertion_point(field_mutable:google.protobuf.Api.source_context) return _msg; @@ -1209,7 +1174,6 @@ inline ::google::protobuf::Syntax Api::_internal_syntax() const { } inline void Api::_internal_set_syntax(::google::protobuf::Syntax value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.syntax_ = value; } @@ -1231,7 +1195,6 @@ template inline PROTOBUF_ALWAYS_INLINE void Method::set_name(Arg_&& arg, Args_... args) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.name_.Set(static_cast(arg), args..., GetArena()); // @@protoc_insertion_point(field_set:google.protobuf.Method.name) } @@ -1246,12 +1209,10 @@ inline const std::string& Method::_internal_name() const { } inline void Method::_internal_set_name(const std::string& value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.name_.Set(value, GetArena()); } inline std::string* Method::_internal_mutable_name() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; return _impl_.name_.Mutable( GetArena()); } inline std::string* Method::release_name() { @@ -1284,7 +1245,6 @@ template inline PROTOBUF_ALWAYS_INLINE void Method::set_request_type_url(Arg_&& arg, Args_... args) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.request_type_url_.Set(static_cast(arg), args..., GetArena()); // @@protoc_insertion_point(field_set:google.protobuf.Method.request_type_url) } @@ -1299,12 +1259,10 @@ inline const std::string& Method::_internal_request_type_url() const { } inline void Method::_internal_set_request_type_url(const std::string& value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.request_type_url_.Set(value, GetArena()); } inline std::string* Method::_internal_mutable_request_type_url() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; return _impl_.request_type_url_.Mutable( GetArena()); } inline std::string* Method::release_request_type_url() { @@ -1342,7 +1300,6 @@ inline bool Method::_internal_request_streaming() const { } inline void Method::_internal_set_request_streaming(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.request_streaming_ = value; } @@ -1360,7 +1317,6 @@ template inline PROTOBUF_ALWAYS_INLINE void Method::set_response_type_url(Arg_&& arg, Args_... args) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.response_type_url_.Set(static_cast(arg), args..., GetArena()); // @@protoc_insertion_point(field_set:google.protobuf.Method.response_type_url) } @@ -1375,12 +1331,10 @@ inline const std::string& Method::_internal_response_type_url() const { } inline void Method::_internal_set_response_type_url(const std::string& value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.response_type_url_.Set(value, GetArena()); } inline std::string* Method::_internal_mutable_response_type_url() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; return _impl_.response_type_url_.Mutable( GetArena()); } inline std::string* Method::release_response_type_url() { @@ -1418,7 +1372,6 @@ inline bool Method::_internal_response_streaming() const { } inline void Method::_internal_set_response_streaming(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.response_streaming_ = value; } @@ -1486,7 +1439,6 @@ inline ::google::protobuf::Syntax Method::_internal_syntax() const { } inline void Method::_internal_set_syntax(::google::protobuf::Syntax value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.syntax_ = value; } @@ -1508,7 +1460,6 @@ template inline PROTOBUF_ALWAYS_INLINE void Mixin::set_name(Arg_&& arg, Args_... args) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.name_.Set(static_cast(arg), args..., GetArena()); // @@protoc_insertion_point(field_set:google.protobuf.Mixin.name) } @@ -1523,12 +1474,10 @@ inline const std::string& Mixin::_internal_name() const { } inline void Mixin::_internal_set_name(const std::string& value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.name_.Set(value, GetArena()); } inline std::string* Mixin::_internal_mutable_name() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; return _impl_.name_.Mutable( GetArena()); } inline std::string* Mixin::release_name() { @@ -1561,7 +1510,6 @@ template inline PROTOBUF_ALWAYS_INLINE void Mixin::set_root(Arg_&& arg, Args_... args) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.root_.Set(static_cast(arg), args..., GetArena()); // @@protoc_insertion_point(field_set:google.protobuf.Mixin.root) } @@ -1576,12 +1524,10 @@ inline const std::string& Mixin::_internal_root() const { } inline void Mixin::_internal_set_root(const std::string& value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.root_.Set(value, GetArena()); } inline std::string* Mixin::_internal_mutable_root() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; return _impl_.root_.Mutable( GetArena()); } inline std::string* Mixin::release_root() { diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index c854413489..023e9c261d 100644 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -26,10 +26,6 @@ #include "google/protobuf/thread_safe_arena.h" -#ifdef ADDRESS_SANITIZER -#include -#endif // ADDRESS_SANITIZER - // Must be included last. #include "google/protobuf/port_def.inc" @@ -91,11 +87,9 @@ class GetDeallocator { space_allocated_(space_allocated) {} void operator()(SizedPtr mem) const { -#ifdef ADDRESS_SANITIZER // This memory was provided by the underlying allocator as unpoisoned, // so return it in an unpoisoned state. - ASAN_UNPOISON_MEMORY_REGION(mem.p, mem.n); -#endif // ADDRESS_SANITIZER + PROTOBUF_UNPOISON_MEMORY_REGION(mem.p, mem.n); if (dealloc_) { dealloc_(mem.p, mem.n); } else { @@ -272,9 +266,7 @@ void SerialArena::AllocateNewBlock(size_t n) { // Previous writes must take effect before writing new head. head_.store(new_head, std::memory_order_release); -#ifdef ADDRESS_SANITIZER - ASAN_POISON_MEMORY_REGION(ptr(), limit_ - ptr()); -#endif // ADDRESS_SANITIZER + PROTOBUF_POISON_MEMORY_REGION(ptr(), limit_ - ptr()); } uint64_t SerialArena::SpaceUsed() const { @@ -681,10 +673,8 @@ ThreadSafeArena::~ThreadSafeArena() { size_t space_allocated = 0; auto mem = Free(&space_allocated); if (alloc_policy_.is_user_owned_initial_block()) { -#ifdef ADDRESS_SANITIZER // Unpoison the initial block, now that it's going back to the user. - ASAN_UNPOISON_MEMORY_REGION(mem.p, mem.n); -#endif // ADDRESS_SANITIZER + PROTOBUF_UNPOISON_MEMORY_REGION(mem.p, mem.n); space_allocated += mem.n; } else if (mem.n > 0) { GetDeallocator(alloc_policy_.get(), &space_allocated)(mem); diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 83beb8f9b4..c52219bf3d 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -10,7 +10,10 @@ #ifndef GOOGLE_PROTOBUF_ARENA_H__ #define GOOGLE_PROTOBUF_ARENA_H__ +#include +#include #include +#include #include #include #include @@ -26,8 +29,11 @@ using type_info = ::type_info; #include #endif +#include "absl/base/attributes.h" #include "absl/log/absl_check.h" +#include "absl/utility/internal/if_constexpr.h" #include "google/protobuf/arena_align.h" +#include "google/protobuf/arena_allocation_policy.h" #include "google/protobuf/port.h" #include "google/protobuf/serial_arena.h" #include "google/protobuf/thread_safe_arena.h" @@ -48,6 +54,9 @@ class Message; // defined in message.h class MessageLite; template class Map; +namespace internal { +struct RepeatedFieldBase; +} // namespace internal namespace arena_metrics { @@ -65,6 +74,7 @@ struct ArenaTestPeer; // defined in arena_test_util.h class InternalMetadata; // defined in metadata_lite.h class LazyField; // defined in lazy_field.h class EpsCopyInputStream; // defined in parse_context.h +class UntypedMapBase; // defined in map.h class RepeatedPtrFieldBase; // defined in repeated_ptr_field.h class TcParser; // defined in generated_message_tctable_impl.h @@ -209,7 +219,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { internal::ThreadSafeArena::kBlockHeaderSize + internal::ThreadSafeArena::kSerialArenaSize; - inline ~Arena() {} + inline ~Arena() = default; // API to create proto2 message objects on the arena. If the arena passed in // is nullptr, then a heap allocated object is returned. Type T must be a @@ -223,36 +233,50 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // allocation protocol, documented above. template PROTOBUF_ALWAYS_INLINE static T* CreateMessage(Arena* arena, Args&&... args) { + using Type = std::remove_const_t; static_assert( - is_arena_constructable::value, + is_arena_constructable::value, "CreateMessage can only construct types that are ArenaConstructable"); - // We must delegate to CreateMaybeMessage() and NOT CreateMessageInternal() - // because protobuf generated classes specialize CreateMaybeMessage() and we - // need to use that specialization for code size reasons. - return Arena::CreateMaybeMessage(arena, static_cast(args)...); +#ifdef __cpp_if_constexpr + constexpr auto construct_type = GetConstructType(); + // We delegate to DefaultConstruct/CopyConstruct where appropriate + // because protobuf generated classes have external templates for these + // functions for code size reasons. + // When `if constexpr` is not available always use the fallback. + if constexpr (construct_type == ConstructType::kDefault) { + return static_cast(DefaultConstruct(arena)); + } else if constexpr (construct_type == ConstructType::kCopy) { + return static_cast(CopyConstruct(arena, &args...)); + } +#endif + return CreateMessageInternal(arena, std::forward(args)...); } - // API to create any objects on the arena. Note that only the object will - // be created on the arena; the underlying ptrs (in case of a proto2 message) - // will be still heap allocated. Proto messages should usually be allocated - // with CreateMessage() instead. + // API to create any objects on the arena. + // + // If an object is arena-constructable, this API behaves like + // Arena::CreateMessage. Arena constructable types are expected to accept + // Arena* as the first argument and one is implicitly added by the API. // - // Note that even if T satisfies the arena message construction protocol - // (InternalArenaConstructable_ trait and optional DestructorSkippable_ - // trait), as described above, this function does not follow the protocol; - // instead, it treats T as a black-box type, just as if it did not have these - // traits. Specifically, T's constructor arguments will always be only those - // passed to Create() -- no additional arena pointer is implicitly added. - // Furthermore, the destructor will always be called at arena destruction time - // (unless the destructor is trivial). Hence, from T's point of view, it is as - // if the object were allocated on the heap (except that the underlying memory - // is obtained from the arena). + // If the object is not arena-constructable, only the object will be created + // on the arena; the underlying ptrs will be still heap allocated. template PROTOBUF_NDEBUG_INLINE static T* Create(Arena* arena, Args&&... args) { - if (PROTOBUF_PREDICT_FALSE(arena == nullptr)) { - return new T(std::forward(args)...); - } - return new (arena->AllocateInternal()) T(std::forward(args)...); + return absl::utility_internal::IfConstexprElse< + is_arena_constructable::value>( + // Arena-constructable + [arena](auto&&... args) { + return CreateMessage(arena, std::forward(args)...); + }, + // Non arena-constructable + [arena](auto&&... args) { + if (PROTOBUF_PREDICT_FALSE(arena == nullptr)) { + return new T(std::forward(args)...); + } + return new (arena->AllocateInternal()) + T(std::forward(args)...); + }, + std::forward(args)...); } // API to delete any objects not on an arena. This can be used to safely @@ -389,32 +413,9 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // mutually exclusive fashion, we use implicit conversions to base classes // to force an explicit ranking for our preferences. The lowest ranked // version that compiles will be accepted. - struct Rank2 {}; - struct Rank1 : Rank2 {}; + struct Rank1 {}; struct Rank0 : Rank1 {}; - static Arena* GetOwningArena(const T* p) { - return GetOwningArena(Rank0{}, p); - } - - template - static auto GetOwningArena(Rank0, const U* p) - -> EnableIfArenaGetOwningArena())> { - return p->GetOwningArena(); - } - - // TODO: remove this function. - template - static auto GetOwningArena(Rank1, const U* p) - -> EnableIfArenaGetArena())> { - return p->GetArena(); - } - - template - static Arena* GetOwningArena(Rank2, const U*) { - return nullptr; - } - static void InternalSwap(T* a, T* b) { a->InternalSwap(b); } static Arena* GetArena(T* p) { return GetArena(Rank0{}, p); } @@ -466,28 +467,10 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { friend class TestUtil::ReflectionTester; }; - // Provides access to protected GetOwningArena to generated messages. For - // internal use only. - template - static Arena* InternalGetOwningArena(T* p) { - ABSL_DCHECK_EQ(InternalHelper::GetOwningArena(p), - InternalHelper::GetArena(p)); - return InternalHelper::GetOwningArena(p); - } - - // Wraps InternalGetArena() and will be removed soon. - // For internal use only. - template - static Arena* InternalGetArenaForAllocation(T* p) { - return InternalHelper::GetArena(p); - } - // Provides access to protected GetArena to generated messages. // For internal use only. template static Arena* InternalGetArena(T* p) { - ABSL_DCHECK_EQ(InternalHelper::GetOwningArena(p), - InternalHelper::GetArena(p)); return InternalHelper::GetArena(p); } @@ -512,6 +495,36 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { private: internal::ThreadSafeArena impl_; + enum class ConstructType { kUnknown, kDefault, kCopy, kMove }; + // Overload set to detect which kind of construction is going to happen for a + // specific set of input arguments. This is used to dispatch to different + // helper functions. + template + static auto ProbeConstructType() + -> std::integral_constant; + template + static auto ProbeConstructType(const T&) + -> std::integral_constant; + template + static auto ProbeConstructType(T&) + -> std::integral_constant; + template + static auto ProbeConstructType(const T&&) + -> std::integral_constant; + template + static auto ProbeConstructType(T&&) + -> std::integral_constant; + template + static auto ProbeConstructType(U&&...) + -> std::integral_constant; + + template + static constexpr auto GetConstructType() { + return std::is_base_of::value + ? decltype(ProbeConstructType(std::declval()...))::value + : ConstructType::kUnknown; + } + void ReturnArrayMemory(void* p, size_t size) { impl_.ReturnArrayMemory(p, size); } @@ -558,31 +571,21 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { } } - // CreateMessage requires that T supports arenas, but this private method - // works whether or not T supports arenas. These are not exposed to user code - // as it can cause confusing API usages, and end up having double free in - // user code. These are used only internally from LazyField and Repeated - // fields, since they are designed to work in all mode combinations. - template - PROTOBUF_ALWAYS_INLINE static Msg* DoCreateMaybeMessage(Arena* arena, - std::true_type, - Args&&... args) { - return CreateMessageInternal(arena, std::forward(args)...); - } - - template - PROTOBUF_ALWAYS_INLINE static T* DoCreateMaybeMessage(Arena* arena, - std::false_type, - Args&&... args) { - return Create(arena, std::forward(args)...); - } - - template - PROTOBUF_ALWAYS_INLINE static T* CreateMaybeMessage(Arena* arena, - Args&&... args) { - return DoCreateMaybeMessage(arena, is_arena_constructable(), - std::forward(args)...); - } + // DefaultConstruct/CopyConstruct: + // + // Functions with a generic signature to support taking the address in generic + // contexts, like RepeatedPtrField, etc. + // These are also used as a hook for `extern template` instantiations where + // codegen can offload the instantiations to the respective .pb.cc files. This + // has two benefits: + // - It reduces the library bloat as callers don't have to instantiate the + // function. + // - It allows the optimizer to see the constructors called to + // further optimize the instantiation. + template + static void* DefaultConstruct(Arena* arena); + template + static void* CopyConstruct(Arena* arena, const void* from); template PROTOBUF_NDEBUG_INLINE T* DoCreateMessage(Args&&... args) { @@ -661,7 +664,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { template friend class internal::GenericTypeHandler; friend class internal::InternalMetadata; // For user_arena(). - friend class internal::LazyField; // For CreateMaybeMessage. + friend class internal::LazyField; // For DefaultConstruct. friend class internal::EpsCopyInputStream; // For parser performance friend class internal::TcParser; // For parser performance friend class MessageLite; @@ -670,9 +673,29 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { template friend class RepeatedField; // For ReturnArrayMemory friend class internal::RepeatedPtrFieldBase; // For ReturnArrayMemory + friend class internal::UntypedMapBase; // For ReturnArenaMemory + friend struct internal::ArenaTestPeer; }; +// DefaultConstruct/CopyConstruct +// +// IMPORTANT: These have to be defined out of line and without an `inline` +// keyword to make sure the `extern template` suppresses instantiations. +template +PROTOBUF_NOINLINE void* Arena::DefaultConstruct(Arena* arena) { + void* mem = arena != nullptr ? arena->AllocateAligned(sizeof(T)) + : ::operator new(sizeof(T)); + return new (mem) T(arena); +} + +template +PROTOBUF_NOINLINE void* Arena::CopyConstruct(Arena* arena, const void* from) { + void* mem = arena != nullptr ? arena->AllocateAligned(sizeof(T)) + : ::operator new(sizeof(T)); + return new (mem) T(arena, *static_cast(from)); +} + template <> inline void* Arena::AllocateInternal() { return impl_.AllocateFromStringBlock(); diff --git a/src/google/protobuf/arena_test_util.h b/src/google/protobuf/arena_test_util.h index e2144a8660..5857056809 100644 --- a/src/google/protobuf/arena_test_util.h +++ b/src/google/protobuf/arena_test_util.h @@ -16,6 +16,9 @@ #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/io/zero_copy_stream_impl_lite.h" +// Must be included last. +#include "google/protobuf/port_def.inc" + namespace google { namespace protobuf { @@ -31,7 +34,12 @@ void TestParseCorruptedString(const T& message) { out.SetSerializationDeterministic(true); message.SerializePartialToCodedStream(&out); } +#if defined(PROTOBUF_ASAN) || defined(PROTOBUF_TSAN) || defined(PROTOBUF_MSAN) + // Make the test smaller in sanitizer mode. + const int kMaxIters = 200; +#else const int kMaxIters = 900; +#endif const int stride = s.size() <= kMaxIters ? 1 : s.size() / kMaxIters; const int start = stride == 1 || use_arena ? 0 : (stride + 1) / 2; for (int i = start; i < s.size(); i += stride) { @@ -62,6 +70,11 @@ struct ArenaTestPeer { static auto PeekCleanupListForTesting(Arena* arena) { return arena->PeekCleanupListForTesting(); } + template + static constexpr auto GetConstructType() { + return Arena::GetConstructType(); + } + using ConstructType = Arena::ConstructType; }; struct CleanupGrowthInfo { @@ -130,4 +143,6 @@ class ArenaHolder { } // namespace protobuf } // namespace google +#include "google/protobuf/port_undef.inc" + #endif // GOOGLE_PROTOBUF_ARENA_TEST_UTIL_H__ diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc index 21041129fb..d1afa07d8f 100644 --- a/src/google/protobuf/arena_unittest.cc +++ b/src/google/protobuf/arena_unittest.cc @@ -11,19 +11,22 @@ #include #include #include +#include #include #include #include #include #include -#include +#include #include #include #include #include "absl/log/absl_check.h" +#include "absl/log/absl_log.h" #include "absl/strings/string_view.h" #include "absl/synchronization/barrier.h" +#include "absl/utility/utility.h" #include "google/protobuf/arena_test_util.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/extension_set.h" @@ -45,7 +48,7 @@ #include "google/protobuf/port_def.inc" using proto2_arena_unittest::ArenaMessage; -using protobuf_unittest::ForeignMessage; +using protobuf_unittest::NestedTestAllTypes; using protobuf_unittest::TestAllExtensions; using protobuf_unittest::TestAllTypes; using protobuf_unittest::TestEmptyMessage; @@ -314,6 +317,80 @@ TEST(ArenaTest, CreateDestroy) { strlen(arena_message->optional_string().c_str())); } +TEST(ArenaTest, MoveCtorOnArena) { + Arena arena; + + ASSERT_EQ(arena.SpaceUsed(), 0); + + auto* original = Arena::CreateMessage(&arena); + TestUtil::SetAllFields(original->mutable_payload()); + TestUtil::ExpectAllFieldsSet(original->payload()); + + auto usage_original = arena.SpaceUsed(); + auto* moved = + Arena::CreateMessage(&arena, std::move(*original)); + auto usage_by_move = arena.SpaceUsed() - usage_original; + + TestUtil::ExpectAllFieldsSet(moved->payload()); + + // The only extra allocation with moves is sizeof(NestedTestAllTypes). + EXPECT_EQ(usage_by_move, sizeof(NestedTestAllTypes)); + EXPECT_LT(usage_by_move + sizeof(TestAllTypes), usage_original); + + // Status after move is unspecified and must not be assumed. It's merely + // checking current implementation specifics for protobuf internal. + TestUtil::ExpectClear(original->payload()); +} + +TEST(ArenaTest, RepeatedFieldMoveCtorOnArena) { + Arena arena; + + auto* original = Arena::CreateMessage>(&arena); + original->Add(1); + original->Add(2); + ASSERT_EQ(original->size(), 2); + ASSERT_EQ(original->Get(0), 1); + ASSERT_EQ(original->Get(1), 2); + + auto* moved = Arena::CreateMessage>( + &arena, std::move(*original)); + + EXPECT_EQ(moved->size(), 2); + EXPECT_EQ(moved->Get(0), 1); + EXPECT_EQ(moved->Get(1), 2); + + // Status after move is unspecified and must not be assumed. It's merely + // checking current implementation specifics for protobuf internal. + EXPECT_EQ(original->size(), 0); +} + +TEST(ArenaTest, RepeatedPtrFieldMoveCtorOnArena) { + Arena arena; + + ASSERT_EQ(arena.SpaceUsed(), 0); + + auto* original = Arena::CreateMessage>(&arena); + auto* msg = original->Add(); + TestUtil::SetAllFields(msg); + TestUtil::ExpectAllFieldsSet(*msg); + + auto usage_original = arena.SpaceUsed(); + auto* moved = Arena::CreateMessage>( + &arena, std::move(*original)); + auto usage_by_move = arena.SpaceUsed() - usage_original; + + EXPECT_EQ(moved->size(), 1); + TestUtil::ExpectAllFieldsSet(moved->Get(0)); + + // The only extra allocation with moves is sizeof(RepeatedPtrField). + EXPECT_EQ(usage_by_move, sizeof(internal::RepeatedPtrFieldBase)); + EXPECT_LT(usage_by_move + sizeof(TestAllTypes), usage_original); + + // Status after move is unspecified and must not be assumed. It's merely + // checking current implementation specifics for protobuf internal. + EXPECT_EQ(original->size(), 0); +} + struct OnlyArenaConstructible { using InternalArenaConstructable_ = void; explicit OnlyArenaConstructible(Arena* arena) {} @@ -324,6 +401,104 @@ TEST(ArenaTest, ArenaOnlyTypesCanBeConstructed) { Arena::CreateMessage(&arena); } +TEST(ArenaTest, GetConstructTypeWorks) { + using T = TestAllTypes; + using Peer = internal::ArenaTestPeer; + using CT = typename Peer::ConstructType; + EXPECT_EQ(CT::kDefault, (Peer::GetConstructType())); + EXPECT_EQ(CT::kCopy, (Peer::GetConstructType())); + EXPECT_EQ(CT::kCopy, (Peer::GetConstructType())); + EXPECT_EQ(CT::kCopy, (Peer::GetConstructType())); + EXPECT_EQ(CT::kMove, (Peer::GetConstructType())); + EXPECT_EQ(CT::kUnknown, (Peer::GetConstructType())); + EXPECT_EQ(CT::kUnknown, (Peer::GetConstructType())); + + // For non-protos, it's always unknown + EXPECT_EQ(CT::kUnknown, (Peer::GetConstructType())); +} + +#ifdef __cpp_if_constexpr +class DispatcherTestProto : public Message { + public: + using InternalArenaConstructable_ = void; + // For the test below to construct. + explicit DispatcherTestProto(absl::in_place_t) {} + explicit DispatcherTestProto(Arena*) { ABSL_LOG(FATAL); } + DispatcherTestProto(Arena*, const DispatcherTestProto&) { ABSL_LOG(FATAL); } + DispatcherTestProto* New(Arena*) const final { ABSL_LOG(FATAL); } + Metadata GetMetadata() const final { ABSL_LOG(FATAL); } + const ClassData* GetClassData() const final { ABSL_LOG(FATAL); } +}; +// We use a specialization to inject behavior for the test. +// This test is very intrusive and will have to be fixed if we change the +// implementation of CreateMessage. +absl::string_view hook_called; +template <> +void* Arena::DefaultConstruct(Arena*) { + hook_called = "default"; + return nullptr; +} +template <> +void* Arena::CopyConstruct(Arena*, const void*) { + hook_called = "copy"; + return nullptr; +} +template <> +DispatcherTestProto* Arena::CreateMessageInternal( + Arena*, int&&) { + hook_called = "fallback"; + return nullptr; +} + +TEST(ArenaTest, CreateArenaConstructable) { + TestAllTypes original; + TestUtil::SetAllFields(&original); + + Arena arena; + auto copied = Arena::Create(&arena, original); + + TestUtil::ExpectAllFieldsSet(*copied); + EXPECT_EQ(copied->GetArena(), &arena); + EXPECT_EQ(copied->optional_nested_message().GetArena(), &arena); +} + +TEST(ArenaTest, CreateRepeatedPtrField) { + Arena arena; + auto repeated = Arena::Create>(&arena); + TestUtil::SetAllFields(repeated->Add()); + + TestUtil::ExpectAllFieldsSet(repeated->Get(0)); + EXPECT_EQ(repeated->GetArena(), &arena); + EXPECT_EQ(repeated->Get(0).GetArena(), &arena); + EXPECT_EQ(repeated->Get(0).optional_nested_message().GetArena(), &arena); +} + +TEST(ArenaTest, CreateMessageDispatchesToSpecialFunctions) { + hook_called = ""; + Arena::CreateMessage(nullptr); + EXPECT_EQ(hook_called, "default"); + + DispatcherTestProto ref(absl::in_place); + const DispatcherTestProto& cref = ref; + + hook_called = ""; + Arena::CreateMessage(nullptr); + EXPECT_EQ(hook_called, "default"); + + hook_called = ""; + Arena::CreateMessage(nullptr, ref); + EXPECT_EQ(hook_called, "copy"); + + hook_called = ""; + Arena::CreateMessage(nullptr, cref); + EXPECT_EQ(hook_called, "copy"); + + hook_called = ""; + Arena::CreateMessage(nullptr, 1); + EXPECT_EQ(hook_called, "fallback"); +} +#endif // __cpp_if_constexpr + TEST(ArenaTest, Parsing) { TestAllTypes original; TestUtil::SetAllFields(&original); @@ -778,20 +953,6 @@ TEST(ArenaTest, AddAllocatedWithReflection) { } TEST(ArenaTest, RepeatedPtrFieldAddClearedTest) { -#ifndef PROTOBUF_FUTURE_REMOVE_CLEARED_API - { - PROTOBUF_IGNORE_DEPRECATION_START - RepeatedPtrField repeated_field; - EXPECT_TRUE(repeated_field.empty()); - EXPECT_EQ(0, repeated_field.size()); - // Ownership is passed to repeated_field. - TestAllTypes* cleared = new TestAllTypes(); - repeated_field.AddCleared(cleared); - EXPECT_TRUE(repeated_field.empty()); - EXPECT_EQ(0, repeated_field.size()); - PROTOBUF_IGNORE_DEPRECATION_STOP - } -#endif // !PROTOBUF_FUTURE_REMOVE_CLEARED_API { RepeatedPtrField repeated_field; EXPECT_TRUE(repeated_field.empty()); @@ -1494,7 +1655,7 @@ TEST(ArenaTest, SpaceReuseForArraysSizeChecks) { } TEST(ArenaTest, SpaceReusePoisonsAndUnpoisonsMemory) { -#ifdef ADDRESS_SANITIZER +#ifdef PROTOBUF_ASAN char buf[1024]{}; constexpr int kSize = 32; { @@ -1528,9 +1689,9 @@ TEST(ArenaTest, SpaceReusePoisonsAndUnpoisonsMemory) { ASSERT_FALSE(__asan_address_is_poisoned(&c)); } -#else // ADDRESS_SANITIZER +#else // PROTOBUF_ASAN GTEST_SKIP(); -#endif // ADDRESS_SANITIZER +#endif // PROTOBUF_ASAN } diff --git a/src/google/protobuf/arenaz_sampler_test.cc b/src/google/protobuf/arenaz_sampler_test.cc index c71162467a..20a0473207 100644 --- a/src/google/protobuf/arenaz_sampler_test.cc +++ b/src/google/protobuf/arenaz_sampler_test.cc @@ -401,6 +401,7 @@ TEST(ThreadSafeArenazSamplerTest, InitialBlockReportsZeroUsedAndWasted) { for (int i = 0; i < 10; ++i) { char block[kSize]; google::protobuf::Arena arena(/*initial_block=*/block, /*initial_block_size=*/kSize); + benchmark::DoNotOptimize(&arena); sampler.Iterate([&](const ThreadSafeArenaStats& h) { const auto& histbin = h.block_histogram[ThreadSafeArenaStats::FindBin(kSize)]; diff --git a/src/google/protobuf/bridge/message_set.proto b/src/google/protobuf/bridge/message_set.proto index 2f23f9b71a..83e8bb0f10 100644 --- a/src/google/protobuf/bridge/message_set.proto +++ b/src/google/protobuf/bridge/message_set.proto @@ -72,5 +72,5 @@ option objc_class_prefix = "GPB"; message MessageSet { option message_set_wire_format = true; - extensions 4 to max; + extensions 4 to max [verification = UNVERIFIED]; } diff --git a/src/google/protobuf/compiler/BUILD.bazel b/src/google/protobuf/compiler/BUILD.bazel index f98c31785b..13a340e7ce 100644 --- a/src/google/protobuf/compiler/BUILD.bazel +++ b/src/google/protobuf/compiler/BUILD.bazel @@ -82,16 +82,36 @@ cc_library( cc_library( name = "versions", + srcs = [ + "versions.cc", + ], hdrs = [ "versions.h", - "versions_suffix.h", ], copts = COPTS, strip_include_prefix = "/src", visibility = [ "//src/google/protobuf/compiler:__subpackages__", ], - deps = ["@com_google_absl//absl/strings"], + deps = [ + ":code_generator", + "//src/google/protobuf:port_def", + "@com_google_absl//absl/log:absl_check", + "@com_google_absl//absl/strings", + ], +) + +cc_test( + name = "versions_test", + size = "small", + srcs = ["versions_test.cc"], + deps = [ + ":versions", + "//src/google/protobuf:test_textproto", + "@com_google_absl//absl/memory", + "@com_google_googletest//:gtest", + "@com_google_googletest//:gtest_main", + ], ) cc_library( @@ -113,7 +133,6 @@ cc_library( ":code_generator", ":importer", ":retention", - "//src/google/protobuf:descriptor_legacy", "//src/google/protobuf:protobuf_nowkt", "//src/google/protobuf/compiler/allowlists", "@com_google_absl//absl/algorithm", @@ -163,7 +182,7 @@ cc_binary( ], copts = COPTS, visibility = [ - "//src/google/protobuf:__subpackages__", + "//:__subpackages__", ], deps = [ ":command_line_interface", @@ -244,6 +263,7 @@ exports_files( visibility = [ "//:__pkg__", "//python:__pkg__", + "//ruby:__pkg__", ], ) @@ -258,7 +278,6 @@ cc_library( deps = [ ":code_generator", "//src/google/protobuf:cc_test_protos", - "//src/google/protobuf:descriptor_legacy", "//src/google/protobuf:descriptor_visitor", "//src/google/protobuf/io", "//src/google/protobuf/stubs", diff --git a/src/google/protobuf/compiler/allowlists/BUILD.bazel b/src/google/protobuf/compiler/allowlists/BUILD.bazel index e6671c05c1..dc84829b21 100644 --- a/src/google/protobuf/compiler/allowlists/BUILD.bazel +++ b/src/google/protobuf/compiler/allowlists/BUILD.bazel @@ -21,10 +21,8 @@ cc_library( cc_library( name = "allowlists", srcs = [ - "editions.cc", "empty_package.cc", "open_enum.cc", - "unused_imports.cc", ], hdrs = ["allowlists.h"], copts = COPTS, diff --git a/src/google/protobuf/compiler/allowlists/editions.cc b/src/google/protobuf/compiler/allowlists/editions.cc deleted file mode 100644 index 6ab81c0646..0000000000 --- a/src/google/protobuf/compiler/allowlists/editions.cc +++ /dev/null @@ -1,31 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2023 Google LLC. All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd - -#include "absl/strings/string_view.h" -#include "google/protobuf/compiler/allowlists/allowlist.h" -#include "google/protobuf/compiler/allowlists/allowlists.h" - -namespace google { -namespace protobuf { -namespace compiler { - -// NOTE: These files have early default access to go/editions. The protoc flag -// `--experimental_editions` can also be used to enable editions. - -static constexpr auto kEarlyEditionsFile = internal::MakeAllowlist( - { -// Intentionally left blank. - "google/protobuf/", - }, - internal::AllowlistFlags::kMatchPrefix); - -bool IsEarlyEditionsFile(absl::string_view file) { - return kEarlyEditionsFile.Allows(file); -} -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/allowlists/unused_imports.cc b/src/google/protobuf/compiler/allowlists/unused_imports.cc deleted file mode 100644 index d9d4b6f70d..0000000000 --- a/src/google/protobuf/compiler/allowlists/unused_imports.cc +++ /dev/null @@ -1,28 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd - -#include "absl/strings/string_view.h" -#include "google/protobuf/compiler/allowlists/allowlist.h" -#include "google/protobuf/compiler/allowlists/allowlists.h" - -namespace google { -namespace protobuf { -namespace compiler { - -// NOTE: Allowlists in this file are not accepting new entries unless otherwise -// specified. -// TODO: Remove when empty. -static constexpr auto kUnusedImports = internal::MakeAllowlist({ -// Intentionally left blank. -}); - -bool IsUnusedImportFile(absl::string_view file) { - return kUnusedImports.Allows(file); -} -} // namespace compiler -} // namespace protobuf -} // namespace google diff --git a/src/google/protobuf/compiler/code_generator_unittest.cc b/src/google/protobuf/compiler/code_generator_unittest.cc index a98214b70c..5ad68126f0 100644 --- a/src/google/protobuf/compiler/code_generator_unittest.cc +++ b/src/google/protobuf/compiler/code_generator_unittest.cc @@ -33,6 +33,8 @@ namespace protobuf { namespace compiler { namespace { +#define ASSERT_OK(x) ASSERT_TRUE(x.ok()) << x.message(); + using ::testing::HasSubstr; using ::testing::NotNull; @@ -168,7 +170,7 @@ TEST_F(CodeGeneratorTest, GetUnresolvedSourceFeaturesInherited) { TEST_F(CodeGeneratorTest, GetResolvedSourceFeaturesRoot) { TestGenerator generator; generator.set_feature_extensions({GetExtensionReflection(pb::test)}); - pool_.SetFeatureSetDefaults(*generator.BuildFeatureSetDefaults()); + ASSERT_OK(pool_.SetFeatureSetDefaults(*generator.BuildFeatureSetDefaults())); ASSERT_THAT(BuildFile(DescriptorProto::descriptor()->file()), NotNull()); ASSERT_THAT(BuildFile(pb::TestMessage::descriptor()->file()), NotNull()); @@ -201,7 +203,7 @@ TEST_F(CodeGeneratorTest, GetResolvedSourceFeaturesRoot) { TEST_F(CodeGeneratorTest, GetResolvedSourceFeaturesInherited) { TestGenerator generator; generator.set_feature_extensions({GetExtensionReflection(pb::test)}); - pool_.SetFeatureSetDefaults(*generator.BuildFeatureSetDefaults()); + ASSERT_OK(pool_.SetFeatureSetDefaults(*generator.BuildFeatureSetDefaults())); ASSERT_THAT(BuildFile(DescriptorProto::descriptor()->file()), NotNull()); ASSERT_THAT(BuildFile(pb::TestMessage::descriptor()->file()), NotNull()); diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index a749f79ce4..e879f149bd 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -17,11 +17,11 @@ #include "absl/algorithm/container.h" #include "absl/container/btree_set.h" #include "absl/container/flat_hash_map.h" +#include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/str_cat.h" #include "absl/types/span.h" #include "google/protobuf/compiler/allowlists/allowlists.h" -#include "google/protobuf/descriptor_legacy.h" #include "google/protobuf/descriptor_visitor.h" #include "google/protobuf/feature_resolver.h" @@ -978,7 +978,8 @@ namespace { bool ContainsProto3Optional(const Descriptor* desc) { for (int i = 0; i < desc->field_count(); i++) { - if (FieldDescriptorLegacy(desc->field(i)).has_optional_keyword()) { + if (desc->field(i)->real_containing_oneof() == nullptr && + desc->field(i)->containing_oneof() != nullptr) { return true; } } @@ -991,8 +992,7 @@ bool ContainsProto3Optional(const Descriptor* desc) { } bool ContainsProto3Optional(const FileDescriptor* file) { - if (FileDescriptorLegacy(file).syntax() == - FileDescriptorLegacy::Syntax::SYNTAX_PROTO3) { + if (file->edition() == Edition::EDITION_PROTO3) { for (int i = 0; i < file->message_type_count(); i++) { if (ContainsProto3Optional(file->message_type(i))) { return true; @@ -1556,7 +1556,8 @@ bool CommandLineInterface::SetupFeatureResolution(DescriptorPool& pool) { ABSL_LOG(ERROR) << defaults.status(); return false; } - pool.SetFeatureSetDefaults(std::move(defaults).value()); + absl::Status status = pool.SetFeatureSetDefaults(std::move(defaults).value()); + ABSL_CHECK(status.ok()) << status.message(); return true; } @@ -1596,9 +1597,10 @@ bool CommandLineInterface::ParseInputFiles( } parsed_files->push_back(parsed_file); - if (!experimental_editions_ && !IsEarlyEditionsFile(parsed_file->name())) { - if (FileDescriptorLegacy(parsed_file).syntax() == - FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS) { + if (!experimental_editions_ && + !absl::StartsWith(parsed_file->name(), "google/protobuf/") && + !absl::StartsWith(parsed_file->name(), "upb/")) { + if (parsed_file->edition() >= Edition::EDITION_2023) { std::cerr << parsed_file->name() << ": This file uses editions, but --experimental_editions has not " @@ -2549,29 +2551,44 @@ bool CommandLineInterface::EnforceProto3OptionalSupport( bool CommandLineInterface::EnforceEditionsSupport( const std::string& codegen_name, uint64_t supported_features, + Edition minimum_edition, Edition maximum_edition, const std::vector& parsed_files) const { - if (supported_features & CodeGenerator::FEATURE_SUPPORTS_EDITIONS) { - // This generator explicitly supports editions. - return true; - } if (experimental_editions_) { // The user has explicitly specified the experimental flag. return true; } for (const auto* fd : parsed_files) { - // Skip enforcement for allowlisted files. - if (IsEarlyEditionsFile(fd->name())) continue; + if (fd->edition() < Edition::EDITION_2023) { + // Legacy proto2/proto3 files don't need any checks. + continue; + } - if (FileDescriptorLegacy(fd).syntax() == - FileDescriptorLegacy::SYNTAX_EDITIONS) { - std::cerr - << fd->name() << ": is an editions file, but code generator " - << codegen_name - << " hasn't been updated to support editions yet. Please ask " - "the owner of this code generator to add support or " - "switch back to proto2/proto3.\n\nSee " - "https://protobuf.dev/editions/overview/ for more information." - << std::endl; + if (absl::StartsWith(fd->name(), "google/protobuf/") || + absl::StartsWith(fd->name(), "upb/")) { + continue; + } + if ((supported_features & CodeGenerator::FEATURE_SUPPORTS_EDITIONS) == 0) { + std::cerr << absl::Substitute( + "$0: is an editions file, but code generator $1 hasn't been " + "updated to support editions yet. Please ask the owner of this code " + "generator to add support or switch back to proto2/proto3.\n\nSee " + "https://protobuf.dev/editions/overview/ for more information.", + fd->name(), codegen_name); + return false; + } + if (fd->edition() < minimum_edition) { + std::cerr << absl::Substitute( + "$0: is a file using edition $2, which isn't supported by code " + "generator $1. Please upgrade your file to at least edition $3.", + fd->name(), codegen_name, fd->edition(), minimum_edition); + return false; + } + if (fd->edition() > maximum_edition) { + std::cerr << absl::Substitute( + "$0: is a file using edition $2, which isn't supported by code " + "generator $1. Please ask the owner of this code generator to add " + "support or switch back to a maximum of edition $3.", + fd->name(), codegen_name, fd->edition(), maximum_edition); return false; } } @@ -2620,7 +2637,9 @@ bool CommandLineInterface::GenerateOutput( if (!EnforceEditionsSupport( output_directive.name, - output_directive.generator->GetSupportedFeatures(), parsed_files)) { + output_directive.generator->GetSupportedFeatures(), + output_directive.generator->GetMinimumEdition(), + output_directive.generator->GetMaximumEdition(), parsed_files)) { return false; } @@ -2824,11 +2843,15 @@ bool CommandLineInterface::GeneratePluginOutput( // Generator returned an error. *error = response.error(); return false; - } else if (!EnforceProto3OptionalSupport( - plugin_name, response.supported_features(), parsed_files)) { + } + if (!EnforceProto3OptionalSupport(plugin_name, response.supported_features(), + parsed_files)) { return false; - } else if (!EnforceEditionsSupport(plugin_name, response.supported_features(), - parsed_files)) { + } + if (!EnforceEditionsSupport(plugin_name, response.supported_features(), + static_cast(response.minimum_edition()), + static_cast(response.maximum_edition()), + parsed_files)) { return false; } diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h index 107c618fb1..4bfee6acd5 100644 --- a/src/google/protobuf/compiler/command_line_interface.h +++ b/src/google/protobuf/compiler/command_line_interface.h @@ -224,6 +224,7 @@ class PROTOC_EXPORT CommandLineInterface { bool EnforceEditionsSupport( const std::string& codegen_name, uint64_t supported_features, + Edition minimum_edition, Edition maximum_edition, const std::vector& parsed_files) const; diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index 88e7412176..d993798d73 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -1530,6 +1530,74 @@ TEST_F(CommandLineInterfaceTest, Plugin_InvalidFeatureExtensionError) { "google.protobuf.FeatureSet"); } +TEST_F(CommandLineInterfaceTest, Plugin_DeprecatedEdition) { + CreateTempFile("foo.proto", R"schema( + edition = "2023"; + message Foo { + int32 i = 1; + } + )schema"); + + SetMockGeneratorTestCase("high_minimum"); + Run("protocol_compiler " + "--proto_path=$tmpdir foo.proto --plug_out=$tmpdir"); + + ExpectErrorSubstring( + "foo.proto: This file uses editions, but --experimental_editions has not " + "been enabled. This syntax is experimental and should be avoided."); +} + +TEST_F(CommandLineInterfaceTest, Plugin_FutureEdition) { + CreateTempFile("foo.proto", R"schema( + edition = "2023"; + message Foo { + int32 i = 1; + } + )schema"); + + SetMockGeneratorTestCase("low_maximum"); + Run("protocol_compiler " + "--proto_path=$tmpdir foo.proto --plug_out=$tmpdir"); + + ExpectErrorSubstring( + "foo.proto: This file uses editions, but --experimental_editions has not " + "been enabled. This syntax is experimental and should be avoided."); +} + +TEST_F(CommandLineInterfaceTest, Plugin_VersionSkewFuture) { + CreateTempFile("foo.proto", R"schema( + edition = "99997_TEST_ONLY"; + message Foo { + int32 i = 1; + } + )schema"); + + SetMockGeneratorTestCase("high_maximum"); + Run("protocol_compiler " + "--proto_path=$tmpdir foo.proto --plug_out=$tmpdir"); + + ExpectErrorSubstring( + "foo.proto:2:5: Edition 99997_TEST_ONLY is later than the maximum " + "supported edition 2023"); +} + +TEST_F(CommandLineInterfaceTest, Plugin_VersionSkewPast) { + CreateTempFile("foo.proto", R"schema( + edition = "1_TEST_ONLY"; + message Foo { + int32 i = 1; + } + )schema"); + + SetMockGeneratorTestCase("low_minimum"); + Run("protocol_compiler " + "--proto_path=$tmpdir foo.proto --plug_out=$tmpdir"); + + ExpectErrorSubstring( + "foo.proto:2:5: Edition 1_TEST_ONLY is earlier than the minimum " + "supported edition PROTO2"); +} + TEST_F(CommandLineInterfaceTest, Plugin_MissingFeatureExtensionError) { CreateTempFile("foo.proto", R"schema( edition = "2023"; diff --git a/src/google/protobuf/compiler/cpp/extension.cc b/src/google/protobuf/compiler/cpp/extension.cc index fcb6f747d1..a06128b771 100644 --- a/src/google/protobuf/compiler/cpp/extension.cc +++ b/src/google/protobuf/compiler/cpp/extension.cc @@ -11,9 +11,13 @@ #include "google/protobuf/compiler/cpp/extension.h" +#include +#include + #include "absl/strings/str_cat.h" #include "absl/strings/str_replace.h" #include "google/protobuf/compiler/cpp/helpers.h" +#include "google/protobuf/compiler/cpp/options.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" #include "google/protobuf/io/printer.h" @@ -23,8 +27,6 @@ namespace protobuf { namespace compiler { namespace cpp { -using ::google::protobuf::internal::cpp::IsLazilyInitializedFile; - ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, const Options& options, MessageSCCAnalyzer* scc_analyzer) @@ -65,6 +67,7 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, variables_["constant_name"] = FieldConstantName(descriptor_); variables_["field_type"] = absl::StrCat(static_cast(descriptor_->type())); + variables_["repeated"] = descriptor_->is_repeated() ? "true" : "false"; variables_["packed"] = descriptor_->is_packed() ? "true" : "false"; variables_["dllexport_decl"] = options.dllexport_decl; @@ -77,96 +80,175 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, variables_["scope"] = scope; variables_["scoped_name"] = ExtensionName(descriptor_); variables_["number"] = absl::StrCat(descriptor_->number()); - - bool add_verify_fn = - // Only verify msgs. - descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - // Options say to verify. - ShouldVerify(descriptor_->message_type(), options_, scc_analyzer_) && - ShouldVerify(descriptor_->containing_type(), options_, scc_analyzer_); - - variables_["verify_fn"] = - add_verify_fn - ? absl::StrCat("&", FieldMessageTypeName(descriptor_, options_), - "::InternalVerify") - : "nullptr"; } -ExtensionGenerator::~ExtensionGenerator() {} +ExtensionGenerator::~ExtensionGenerator() = default; bool ExtensionGenerator::IsScoped() const { return descriptor_->extension_scope() != nullptr; } -void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) const { - Formatter format(printer, variables_); - - // If this is a class member, it needs to be declared "static". Otherwise, - // it needs to be "extern". In the latter case, it also needs the DLL - // export/import specifier. - std::string qualifier; - if (!IsScoped()) { - qualifier = "extern"; - if (!options_.dllexport_decl.empty()) { - qualifier = absl::StrCat(options_.dllexport_decl, " ", qualifier); - } - } else { - qualifier = "static"; - } +void ExtensionGenerator::GenerateDeclaration(io::Printer* p) const { + auto var = p->WithVars(variables_); + auto annotate = p->WithAnnotations({{"name", descriptor_}}); - format( - "static const int $constant_name$ = $number$;\n" - "$1$ ::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n" - " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$ >\n" - " ${2$$name$$}$;\n", - qualifier, descriptor_); + p->Emit({{"qualifier", + // If this is a class member, it needs to be declared "static". + // Otherwise, it needs to be "extern". In the latter case, it + // also needs the DLL export/import specifier. + IsScoped() ? "static" + : options_.dllexport_decl.empty() + ? "extern" + : absl::StrCat(options_.dllexport_decl, " extern")}}, + R"cc( + static const int $constant_name$ = $number$; + $qualifier$ ::$proto_ns$::internal::ExtensionIdentifier< + $extendee$, ::$proto_ns$::internal::$type_traits$, $field_type$, + $packed$> + $name$; + )cc"); } -void ExtensionGenerator::GenerateDefinition(io::Printer* printer) { - Formatter format(printer, variables_); - std::string default_str; - // If this is a class member, it needs to be declared in its class scope. - if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { - // We need to declare a global string which will contain the default value. - // We cannot declare it at class scope because that would require exposing - // it in the header which would be annoying for other reasons. So we - // replace :: with _ in the name and declare it as a global. - default_str = - absl::StrReplaceAll(variables_["scoped_name"], {{"::", "_"}}) + - "_default"; - format("const std::string $1$($2$);\n", default_str, - DefaultValue(options_, descriptor_)); - } else if (descriptor_->message_type()) { - // We have to initialize the default instance for extensions at registration - // time. - default_str = absl::StrCat(FieldMessageTypeName(descriptor_, options_), - "::default_instance()"); - } else { - default_str = DefaultValue(options_, descriptor_); - } +void ExtensionGenerator::GenerateDefinition(io::Printer* p) { + auto vars = p->WithVars(variables_); + auto generate_default_string = [&] { + if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { + // We need to declare a global string which will contain the default + // value. We cannot declare it at class scope because that would require + // exposing it in the header which would be annoying for other reasons. So + // we replace :: with _ in the name and declare it as a global. + return absl::StrReplaceAll(variables_["scoped_name"], {{"::", "_"}}) + + "_default"; + } else if (descriptor_->message_type()) { + // We have to initialize the default instance for extensions at + // registration time. + return absl::StrCat("&", QualifiedDefaultInstanceName( + descriptor_->message_type(), options_)); + } else { + return DefaultValue(options_, descriptor_); + } + }; - // Likewise, class members need to declare the field constant variable. - if (IsScoped()) { - format( - "#if !defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)\n" - "const int $scope$$constant_name$;\n" - "#endif\n"); - } + auto local_var = p->WithVars({ + {"default_str", generate_default_string()}, + {"default_val", DefaultValue(options_, descriptor_)}, + {"message_type", descriptor_->message_type() != nullptr + ? FieldMessageTypeName(descriptor_, options_) + : ""}, + }); + p->Emit( + { + {"declare_default_str", + [&] { + if (descriptor_->cpp_type() != FieldDescriptor::CPPTYPE_STRING) + return; - if (IsLazilyInitializedFile(descriptor_->file()->name())) { - format( - "PROTOBUF_CONSTINIT$ dllexport_decl$ " - "PROTOBUF_ATTRIBUTE_INIT_PRIORITY2\n" - "::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n" - " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$>\n" - " $scoped_name$($constant_name$);\n"); - } else { - format( - "$dllexport_decl $PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 " - "::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n" - " ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$>\n" - " $scoped_name$($constant_name$, $1$, $verify_fn$);\n", - default_str); + // If this is a class member, it needs to be declared in its class + // scope. + p->Emit(R"cc( + const std::string $default_str$($default_val$); + )cc"); + }}, + {"declare_const_var", + [&] { + if (!IsScoped()) return; + // Likewise, class members need to declare the field constant + // variable. + p->Emit(R"cc( +#if !defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912) + const int $scope$$constant_name$; +#endif + )cc"); + }}, + {"define_extension_id", + [&] { + p->Emit(R"cc( + PROTOBUF_CONSTINIT$ dllexport_decl$ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi:: + ExtensionIdentifier<$extendee$, ::_pbi::$type_traits$, + $field_type$, $packed$> + $scoped_name$($constant_name$, $default_str$); + )cc"); + }}, + }, + R"cc( + $declare_default_str$; + $declare_const_var$; + $define_extension_id$; + )cc"); +} + +void ExtensionGenerator::GenerateRegistration(io::Printer* p) { + auto vars = p->WithVars(variables_); + switch (descriptor_->cpp_type()) { + case FieldDescriptor::CPPTYPE_ENUM: + p->Emit({{"enum_name", ClassName(descriptor_->enum_type(), true)}}, + R"cc( + ::_pbi::ExtensionSet::RegisterEnumExtension( + &$extendee$::default_instance(), $number$, $field_type$, + $repeated$, $packed$, $enum_name$_IsValid), + )cc"); + break; + case FieldDescriptor::CPPTYPE_MESSAGE: { + const bool should_verify = + // Only verify msgs. + descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && + // Options say to verify. + ShouldVerify(descriptor_->message_type(), options_, scc_analyzer_) && + ShouldVerify(descriptor_->containing_type(), options_, scc_analyzer_); + const auto message_type = FieldMessageTypeName(descriptor_, options_); + auto v = p->WithVars( + {{"verify", should_verify + ? absl::StrCat("&", message_type, "::InternalVerify") + : "nullptr"}, + {"message_type", message_type}, + {"lazy", descriptor_->options().has_lazy() + ? descriptor_->options().lazy() ? "kLazy" : "kEager" + : "kUndefined"}}); + if (UsingImplicitWeakDescriptor(descriptor_->file(), options_)) { + const auto find_index = [](auto* desc) { + const std::vector msgs = + FlattenMessagesInFile(desc->file()); + return absl::c_find(msgs, desc) - msgs.begin(); + }; + p->Emit( + { + {"extendee_table", + DescriptorTableName(descriptor_->containing_type()->file(), + options_)}, + {"extendee_index", find_index(descriptor_->containing_type())}, + {"extension_table", + DescriptorTableName(descriptor_->message_type()->file(), + options_)}, + {"extension_index", find_index(descriptor_->message_type())}, + }, + R"cc( + ::_pbi::ExtensionSet::RegisterMessageExtension( + ::_pbi::GetPrototypeForWeakDescriptor(&$extendee_table$, + $extendee_index$), + $number$, $field_type$, $repeated$, $packed$, + ::_pbi::GetPrototypeForWeakDescriptor(&$extension_table$, + $extension_index$), + $verify$, ::_pbi::LazyAnnotation::$lazy$), + )cc"); + } else { + p->Emit(R"cc( + ::_pbi::ExtensionSet::RegisterMessageExtension( + &$extendee$::default_instance(), $number$, $field_type$, + $repeated$, $packed$, &$message_type$::default_instance(), + $verify$, ::_pbi::LazyAnnotation::$lazy$), + )cc"); + } + break; + } + default: + p->Emit( + R"cc( + ::_pbi::ExtensionSet::RegisterExtension( + &$extendee$::default_instance(), $number$, $field_type$, + $repeated$, $packed$), + )cc"); + break; } } diff --git a/src/google/protobuf/compiler/cpp/extension.h b/src/google/protobuf/compiler/cpp/extension.h index 406bb634bc..0558d65901 100644 --- a/src/google/protobuf/compiler/cpp/extension.h +++ b/src/google/protobuf/compiler/cpp/extension.h @@ -51,10 +51,12 @@ class PROTOC_EXPORT ExtensionGenerator { ~ExtensionGenerator(); // Header stuff. - void GenerateDeclaration(io::Printer* printer) const; + void GenerateDeclaration(io::Printer* p) const; // Source file stuff. - void GenerateDefinition(io::Printer* printer); + void GenerateDefinition(io::Printer* p); + + void GenerateRegistration(io::Printer* p); bool IsScoped() const; diff --git a/src/google/protobuf/compiler/cpp/field.cc b/src/google/protobuf/compiler/cpp/field.cc index e9ccf46bbd..a8a73ecd67 100644 --- a/src/google/protobuf/compiler/cpp/field.cc +++ b/src/google/protobuf/compiler/cpp/field.cc @@ -262,8 +262,8 @@ std::unique_ptr MakeGenerator(const FieldDescriptor* field, void HasBitVars(const FieldDescriptor* field, const Options& opts, absl::optional idx, std::vector& vars) { if (!idx.has_value()) { - vars.emplace_back("set_hasbit", ""); - vars.emplace_back("clear_hasbit", ""); + vars.emplace_back(Sub("set_hasbit", "").WithSuffix(";")); + vars.emplace_back(Sub("clear_hasbit", "").WithSuffix(";")); return; } @@ -293,7 +293,7 @@ void InlinedStringVars(const FieldDescriptor* field, const Options& opts, } // The first bit is the tracking bit for on demand registering ArenaDtor. - ABSL_CHECK_GT(*idx, 0) + ABSL_CHECK_GT(*idx, 0u) << "_inlined_string_donated_'s bit 0 is reserved for arena dtor tracking"; int32_t index = *idx / 32; diff --git a/src/google/protobuf/compiler/cpp/field.h b/src/google/protobuf/compiler/cpp/field.h index 1bba5f27b5..764c87f0d0 100644 --- a/src/google/protobuf/compiler/cpp/field.h +++ b/src/google/protobuf/compiler/cpp/field.h @@ -39,6 +39,11 @@ namespace cpp { // matter of clean composability. class FieldGeneratorBase { public: + // `GeneratorFunction` defines a subset of generator functions that may have + // additional optimizations or requirements such as 'uses a local `arena` + // variable instead of calling GetArena()' + enum class GeneratorFunction { kMergeFrom }; + FieldGeneratorBase(const FieldDescriptor* descriptor, const Options& options, MessageSCCAnalyzer* scc_analyzer); @@ -100,6 +105,10 @@ class FieldGeneratorBase { return has_default_constexpr_constructor_; } + // Returns true if this generator requires an 'arena' parameter on the + // given generator function. + virtual bool RequiresArena(GeneratorFunction) const { return false; } + virtual std::vector MakeVars() const { return {}; } virtual void GeneratePrivateMembers(io::Printer* p) const = 0; @@ -112,10 +121,6 @@ class FieldGeneratorBase { virtual void GenerateNonInlineAccessorDefinitions(io::Printer* p) const {} - virtual void GenerateInternalAccessorDefinitions(io::Printer* p) const {} - - virtual void GenerateInternalAccessorDeclarations(io::Printer* p) const {} - virtual void GenerateClearingCode(io::Printer* p) const = 0; virtual void GenerateMessageClearingCode(io::Printer* p) const { @@ -230,6 +235,8 @@ class FieldGenerator { } public: + using GeneratorFunction = FieldGeneratorBase::GeneratorFunction; + FieldGenerator(const FieldGenerator&) = delete; FieldGenerator& operator=(const FieldGenerator&) = delete; FieldGenerator(FieldGenerator&&) = default; @@ -256,6 +263,11 @@ class FieldGenerator { return impl_->has_default_constexpr_constructor(); } + // Requirements: see FieldGeneratorBase for documentation + bool RequiresArena(GeneratorFunction function) const { + return impl_->RequiresArena(function); + } + // Prints private members needed to represent this field. // // These are placed inside the class definition. @@ -318,18 +330,6 @@ class FieldGenerator { impl_->GenerateNonInlineAccessorDefinitions(p); } - // Generates declarations of accessors that are for internal purposes only. - void GenerateInternalAccessorDefinitions(io::Printer* p) const { - auto vars = PushVarsForCall(p); - impl_->GenerateInternalAccessorDefinitions(p); - } - - // Generates definitions of accessors that are for internal purposes only. - void GenerateInternalAccessorDeclarations(io::Printer* p) const { - auto vars = PushVarsForCall(p); - impl_->GenerateInternalAccessorDeclarations(p); - } - // Generates statements which clear the field. // // This is used to define the clear_$name$() method. diff --git a/src/google/protobuf/compiler/cpp/field_generators/cord_field.cc b/src/google/protobuf/compiler/cpp/field_generators/cord_field.cc index 62cbbae303..ffcf3dce90 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/cord_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/cord_field.cc @@ -119,8 +119,10 @@ class CordOneofFieldGenerator : public CordFieldGenerator { void GenerateInlineAccessorDefinitions(io::Printer* printer) const override; void GenerateNonInlineAccessorDefinitions( io::Printer* printer) const override; + bool RequiresArena(GeneratorFunction func) const override; void GenerateClearingCode(io::Printer* printer) const override; void GenerateSwappingCode(io::Printer* printer) const override; + void GenerateMergingCode(io::Printer* printer) const override; void GenerateConstructorCode(io::Printer* printer) const override {} void GenerateArenaDestructorCode(io::Printer* printer) const override; // Overrides CordFieldGenerator behavior. @@ -347,21 +349,17 @@ void CordOneofFieldGenerator::GenerateInlineAccessorDefinitions( } )cc"); printer->Emit(R"cc( - inline void $classname$::_internal_set_$name$(const ::absl::Cord& value) { + inline void $classname$::set_$name$(const ::absl::Cord& value) { if ($not_has_field$) { clear_$oneof_name$(); set_has_$name$(); $field$ = new ::absl::Cord; - if (GetArena() != nullptr) { - GetArena()->Own($field$); + ::$proto_ns$::Arena* arena = GetArena(); + if (arena != nullptr) { + arena->Own($field$); } } *$field$ = value; - } - )cc"); - printer->Emit(R"cc( - inline void $classname$::set_$name$(const ::absl::Cord& value) { - _internal_set_$name$(value); $annotate_set$; // @@protoc_insertion_point(field_set:$full_name$) } @@ -372,8 +370,9 @@ void CordOneofFieldGenerator::GenerateInlineAccessorDefinitions( clear_$oneof_name$(); set_has_$name$(); $field$ = new ::absl::Cord; - if (GetArena() != nullptr) { - GetArena()->Own($field$); + ::$proto_ns$::Arena* arena = GetArena(); + if (arena != nullptr) { + arena->Own($field$); } } *$field$ = value; @@ -387,8 +386,9 @@ void CordOneofFieldGenerator::GenerateInlineAccessorDefinitions( clear_$oneof_name$(); set_has_$name$(); $field$ = new ::absl::Cord; - if (GetArena() != nullptr) { - GetArena()->Own($field$); + ::$proto_ns$::Arena* arena = GetArena(); + if (arena != nullptr) { + arena->Own($field$); } } return $field$; @@ -408,6 +408,14 @@ void CordOneofFieldGenerator::GenerateNonInlineAccessorDefinitions( } } +bool CordOneofFieldGenerator::RequiresArena(GeneratorFunction func) const { + switch (func) { + case GeneratorFunction::kMergeFrom: + return true; + } + return false; +} + void CordOneofFieldGenerator::GenerateClearingCode(io::Printer* printer) const { Formatter format(printer, variables_); format( @@ -426,6 +434,15 @@ void CordOneofFieldGenerator::GenerateArenaDestructorCode( // default behavior here. } +void CordOneofFieldGenerator::GenerateMergingCode(io::Printer* printer) const { + printer->Emit(R"cc( + if (oneof_needs_init) { + _this->$field$ = ::$proto_ns$::Arena::Create(arena); + } + *_this->$field$ = *from.$field$; + )cc"); +} + // =================================================================== } // namespace diff --git a/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc b/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc index 51a20ce5d0..1b5287960a 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc @@ -74,7 +74,7 @@ class SingularEnum : public FieldGeneratorBase { void GenerateMergingCode(io::Printer* p) const override { p->Emit(R"cc( - _this->_internal_set_$name$(from._internal_$name$()); + _this->$field_$ = from.$field_$; )cc"); } @@ -169,33 +169,37 @@ void SingularEnum::GenerateInlineAccessorDefinitions(io::Printer* p) const { // @@protoc_insertion_point(field_get:$pkg.Msg.field$) return _internal_$name$(); } - inline void $Msg$::set_$name$($Enum$ value) { - $PrepareSplitMessageForWrite$; - _internal_set_$name$(value); - $annotate_set$; - // @@protoc_insertion_point(field_set:$pkg.Msg.field$) - } )cc"); if (is_oneof()) { p->Emit(R"cc( - inline $Enum$ $Msg$::_internal_$name$() const { - if ($has_field$) { - return static_cast<$Enum$>($field_$); - } - return static_cast<$Enum$>($kDefault$); - } - inline void $Msg$::_internal_set_$name$($Enum$ value) { + inline void $Msg$::set_$name$($Enum$ value) { + $PrepareSplitMessageForWrite$; $assert_valid$; if ($not_has_field$) { clear_$oneof_name$(); set_has_$name$(); } $field_$ = value; + $annotate_set$; + // @@protoc_insertion_point(field_set:$pkg.Msg.field$) + } + inline $Enum$ $Msg$::_internal_$name$() const { + if ($has_field$) { + return static_cast<$Enum$>($field_$); + } + return static_cast<$Enum$>($kDefault$); } )cc"); } else { p->Emit(R"cc( + inline void $Msg$::set_$name$($Enum$ value) { + $PrepareSplitMessageForWrite$; + _internal_set_$name$(value); + $set_hasbit$; + $annotate_set$; + // @@protoc_insertion_point(field_set:$pkg.Msg.field$) + } inline $Enum$ $Msg$::_internal_$name$() const { $TsanDetectConcurrentRead$; return static_cast<$Enum$>($field_$); @@ -203,7 +207,6 @@ void SingularEnum::GenerateInlineAccessorDefinitions(io::Printer* p) const { inline void $Msg$::_internal_set_$name$($Enum$ value) { $TsanDetectConcurrentMutation$; $assert_valid$; - $set_hasbit$; $field_$ = value; } )cc"); diff --git a/src/google/protobuf/compiler/cpp/field_generators/message_field.cc b/src/google/protobuf/compiler/cpp/field_generators/message_field.cc index 34c7733eac..b2b20dec3e 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/message_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/message_field.cc @@ -102,12 +102,12 @@ class SingularMessage : public FieldGeneratorBase { )cc"); } + bool RequiresArena(GeneratorFunction function) const override; + void GenerateNonInlineAccessorDefinitions(io::Printer* p) const override {} void GenerateAccessorDeclarations(io::Printer* p) const override; void GenerateInlineAccessorDefinitions(io::Printer* p) const override; - void GenerateInternalAccessorDeclarations(io::Printer* p) const override; - void GenerateInternalAccessorDefinitions(io::Printer* p) const override; void GenerateClearingCode(io::Printer* p) const override; void GenerateMessageClearingCode(io::Printer* p) const override; void GenerateMergingCode(io::Printer* p) const override; @@ -131,12 +131,13 @@ class SingularMessage : public FieldGeneratorBase { } void GenerateMemberCopyConstructor(io::Printer* p) const override { - p->Emit("$name$_{CreateMaybeMessage<$Submsg$>(arena, *from.$name$_)}"); + p->Emit( + "$name$_{$superclass$::CopyConstruct<$Submsg$>(arena, *from.$name$_)}"); } void GenerateOneofCopyConstruct(io::Printer* p) const override { p->Emit(R"cc( - $field$ = CreateMaybeMessage<$Submsg$>(arena, *from.$field$); + $field$ = $superclass$::CopyConstruct<$Submsg$>(arena, *from.$field$); )cc"); } @@ -258,9 +259,8 @@ void SingularMessage::GenerateInlineAccessorDefinitions(io::Printer* p) const { inline $Submsg$* $Msg$::_internal_mutable_$name$() { $TsanDetectConcurrentMutation$; $StrongRef$; - $set_hasbit$; if ($field_$ == nullptr) { - auto* p = CreateMaybeMessage<$Submsg$>(GetArena()); + auto* p = $superclass$::DefaultConstruct<$Submsg$>(GetArena()); $field_$ = reinterpret_cast<$MemberType$*>(p); } return $cast_field_$; @@ -269,6 +269,7 @@ void SingularMessage::GenerateInlineAccessorDefinitions(io::Printer* p) const { //~ TODO: add tests to make sure all write accessors are //~ able to prepare split message allocation. $PrepareSplitMessageForWrite$; + $set_hasbit$; $Submsg$* _msg = _internal_mutable_$name$(); $annotate_mutable$; // @@protoc_insertion_point(field_mutable:$pkg.Msg.field$) @@ -304,87 +305,6 @@ void SingularMessage::GenerateInlineAccessorDefinitions(io::Printer* p) const { )cc"); } -void SingularMessage::GenerateInternalAccessorDeclarations( - io::Printer* p) const { - if (!is_weak()) { - p->Emit(R"cc( - static const $Submsg$& $name$(const $Msg$* msg); - )cc"); - return; - } - - p->Emit(R"cc( - static const $pb$::MessageLite& $name$(const $Msg$* msg); - static $pb$::MessageLite* mutable_$name$($Msg$* msg); - )cc"); -} - -void SingularMessage::GenerateInternalAccessorDefinitions( - io::Printer* p) const { - // In theory, these accessors could be inline in _Internal. However, in - // practice, the linker is then not able to throw them out making implicit - // weak dependencies not work at all. - - if (!is_weak()) { - // This inline accessor directly returns member field and is used in - // Serialize such that AFDO profile correctly captures access information to - // message fields under serialize. - p->Emit(R"cc( - const $Submsg$& $Msg$::_Internal::$name$(const $Msg$* msg) { - return *msg->$field_$; - } - )cc"); - return; - } - - // These private accessors are used by MergeFrom and - // MergePartialFromCodedStream, and their purpose is to provide access to - // the field without creating a strong dependency on the message type. - p->Emit( - { - {"update_hasbit", - [&] { - if (!has_hasbit_) return; - p->Emit(R"cc( - msg->$set_hasbit$; - )cc"); - }}, - {"is_already_set", - [&] { - if (!is_oneof()) { - p->Emit("msg->$field_$ == nullptr"); - } else { - p->Emit("msg->$not_has_field$"); - } - }}, - {"clear_oneof", - [&] { - if (!is_oneof()) return; - p->Emit(R"cc( - msg->clear_$oneof_name$(); - msg->set_has_$name$(); - )cc"); - }}, - }, - R"cc( - const $pb$::MessageLite& $Msg$::_Internal::$name$(const $Msg$* msg) { - if (msg->$field_$ != nullptr) { - return *msg->$field_$; - } else { - return *$kDefaultPtr$; - } - } - $pb$::MessageLite* $Msg$::_Internal::mutable_$name$($Msg$* msg) { - $update_hasbit$; - if ($is_already_set$) { - $clear_oneof$; - msg->$field_$ = $kDefaultPtr$->New(msg->GetArena()); - } - return msg->$field_$; - } - )cc"); -} - void SingularMessage::GenerateClearingCode(io::Printer* p) const { if (!has_hasbit_) { // If we don't have has-bits, message presence is indicated only by ptr != @@ -415,15 +335,42 @@ void SingularMessage::GenerateMessageClearingCode(io::Printer* p) const { } } +bool SingularMessage::RequiresArena(GeneratorFunction function) const { + switch (function) { + case GeneratorFunction::kMergeFrom: + return !should_split(); + } + return false; +} + void SingularMessage::GenerateMergingCode(io::Printer* p) const { if (is_weak()) { p->Emit( - "_Internal::mutable_$name$(_this)->CheckTypeAndMergeFrom(\n" - " _Internal::$name$(&from));\n"); - } else { + R"cc( + if (_this->$field_$ == nullptr) { + _this->$field_$ = from.$field_$->New(arena); + } + _this->$field_$->CheckTypeAndMergeFrom(*from.$field_$); + )cc"); + } else if (should_split()) { p->Emit( "_this->_internal_mutable_$name$()->$Submsg$::MergeFrom(\n" " from._internal_$name$());\n"); + } else { + // Important: we set `hasbits` after we copied the field. There are cases + // where people assign root values to child values or vice versa which + // are not always checked, so we delay this change becoming 'visibile' + // until after we copied the message. + // TODO enforces this as undefined behavior in debug builds. + p->Emit(R"cc( + $DCHK$(from.$field_$ != nullptr); + if (_this->$field_$ == nullptr) { + _this->$field_$ = + $superclass$::CopyConstruct<$Submsg$>(arena, *from.$field_$); + } else { + _this->$field_$->MergeFrom(*from.$field_$); + } + )cc"); } } @@ -449,13 +396,15 @@ void SingularMessage::GenerateCopyConstructorCode(io::Printer* p) const { if (has_hasbit_) { p->Emit(R"cc( if ((from.$has_hasbit$) != 0) { - _this->$field_$ = CreateMaybeMessage<$Submsg$>(arena, *from.$field_$); + _this->$field_$ = + $superclass$::CopyConstruct<$Submsg$>(arena, *from.$field_$); } )cc"); } else { p->Emit(R"cc( if (from._internal_has_$name$()) { - _this->$field_$ = CreateMaybeMessage<$Submsg$>(arena, *from.$field_$); + _this->$field_$ = + $superclass$::CopyConstruct<$Submsg$>(arena, *from.$field_$); } )cc"); } @@ -466,14 +415,13 @@ void SingularMessage::GenerateSerializeWithCachedSizesToArray( if (!is_group()) { p->Emit(R"cc( target = $pbi$::WireFormatLite::InternalWrite$declared_type$( - $number$, _Internal::$name$(this), - _Internal::$name$(this).GetCachedSize(), target, stream); + $number$, *$field_$, $field_$->GetCachedSize(), target, stream); )cc"); } else { p->Emit(R"cc( target = stream->EnsureSpace(target); target = $pbi$::WireFormatLite::InternalWrite$declared_type$( - $number$, _Internal::$name$(this), target, stream); + $number$, *$field_$, target, stream); )cc"); } } @@ -544,6 +492,8 @@ class OneofMessage : public SingularMessage { void GenerateDestructorCode(io::Printer* p) const override; void GenerateConstructorCode(io::Printer* p) const override; void GenerateIsInitialized(io::Printer* p) const override; + void GenerateMergingCode(io::Printer* p) const override; + bool RequiresArena(GeneratorFunction func) const override; }; void OneofMessage::GenerateNonInlineAccessorDefinitions(io::Printer* p) const { @@ -636,7 +586,8 @@ void OneofMessage::GenerateInlineAccessorDefinitions(io::Printer* p) const { if ($not_has_field$) { clear_$oneof_name$(); set_has_$name$(); - $field_$ = $weak_cast$(CreateMaybeMessage<$Submsg$>(GetArena())); + $field_$ = + $weak_cast$($superclass$::DefaultConstruct<$Submsg$>(GetArena())); } return $cast_field_$; } @@ -684,6 +635,34 @@ void OneofMessage::GenerateIsInitialized(io::Printer* p) const { )cc"); } +void OneofMessage::GenerateMergingCode(io::Printer* p) const { + if (is_weak()) { + p->Emit(R"cc( + if (oneof_needs_init) { + _this->$field_$ = from.$field_$->New(arena); + } + _this->$field_$->CheckTypeAndMergeFrom(*from.$field_$); + )cc"); + } else { + p->Emit(R"cc( + if (oneof_needs_init) { + _this->$field_$ = + $superclass$::CopyConstruct<$Submsg$>(arena, *from.$field_$); + } else { + _this->$field_$->MergeFrom(from._internal_$name$()); + } + )cc"); + } +} + +bool OneofMessage::RequiresArena(GeneratorFunction func) const { + switch (func) { + case GeneratorFunction::kMergeFrom: + return true; + } + return false; +} + class RepeatedMessage : public FieldGeneratorBase { public: RepeatedMessage(const FieldDescriptor* field, const Options& opts, @@ -729,34 +708,33 @@ void RepeatedMessage::GeneratePrivateMembers(io::Printer* p) const { } void RepeatedMessage::GenerateAccessorDeclarations(io::Printer* p) const { - Formatter format(p); - format("$DEPRECATED$ $Submsg$* ${1$mutable_$name$$}$(int index);\n", - std::make_tuple(field_, GeneratedCodeInfo::Annotation::ALIAS)); - format( - "$DEPRECATED$ $pb$::RepeatedPtrField< $Submsg$ >*\n" - " ${1$mutable_$name$$}$();\n", - std::make_tuple(field_, GeneratedCodeInfo::Annotation::ALIAS)); - format( - "private:\n" - "const $pb$::RepeatedPtrField<$Submsg$>& _internal_$name$() const;\n" - "$pb$::RepeatedPtrField<$Submsg$>* _internal_mutable_$name$();\n"); + auto v = p->WithVars( + AnnotatedAccessors(field_, {"", "_internal_", "_internal_mutable_"})); + auto vs = p->WithVars( + AnnotatedAccessors(field_, {"add_"}, io::AnnotationCollector::kSet)); + auto vm = p->WithVars(AnnotatedAccessors(field_, {"mutable_"}, + io::AnnotationCollector::kAlias)); + + p->Emit(R"cc( + $DEPRECATED$ $Submsg$* $mutable_name$(int index); + $DEPRECATED$ $pb$::RepeatedPtrField<$Submsg$>* $mutable_name$(); + + private: + const $pb$::RepeatedPtrField<$Submsg$>& $_internal_name$() const; + $pb$::RepeatedPtrField<$Submsg$>* $_internal_mutable_name$(); + )cc"); if (is_weak()) { - format( - "const $pb$::WeakRepeatedPtrField<$Submsg$>& _internal_weak_$name$() " - "const;\n" - "$pb$::WeakRepeatedPtrField<$Submsg$>* " - "_internal_mutable_weak_$name$();\n"); + p->Emit(R"cc( + const $pb$::WeakRepeatedPtrField<$Submsg$>& _internal_weak_$name$() const; + $pb$::WeakRepeatedPtrField<$Submsg$>* _internal_mutable_weak_$name$(); + )cc"); } - format( - "public:\n" - "$DEPRECATED$ const $Submsg$& ${1$$name$$}$(int index) const;\n", - field_); - format("$DEPRECATED$ $Submsg$* ${1$add_$name$$}$();\n", - std::make_tuple(field_, GeneratedCodeInfo::Annotation::SET)); - format( - "$DEPRECATED$ const $pb$::RepeatedPtrField< $Submsg$ >&\n" - " ${1$$name$$}$() const;\n", - field_); + p->Emit(R"cc( + public: + $DEPRECATED$ const $Submsg$& $name$(int index) const; + $DEPRECATED$ $Submsg$* $add_name$(); + $DEPRECATED$ const $pb$::RepeatedPtrField<$Submsg$>& $name$() const; + )cc"); } void RepeatedMessage::GenerateInlineAccessorDefinitions(io::Printer* p) const { @@ -830,9 +808,8 @@ void RepeatedMessage::GenerateInlineAccessorDefinitions(io::Printer* p) const { $TsanDetectConcurrentRead$; $PrepareSplitMessageForWrite$; if ($field_$.IsDefault()) { - $field_$.Set( - CreateMaybeMessage<$pb$::$Weak$RepeatedPtrField<$Submsg$>>( - GetArena())); + $field_$.Set($superclass$::DefaultConstruct< + $pb$::$Weak$RepeatedPtrField<$Submsg$>>(GetArena())); } return $field_$.Get(); } diff --git a/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc b/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc index f58b9b3eeb..eaa00a17a8 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc @@ -108,7 +108,7 @@ class SingularPrimitive final : public FieldGeneratorBase { void GenerateMergingCode(io::Printer* p) const override { p->Emit(R"cc( - _this->_internal_set_$name$(from._internal_$name$()); + _this->$field_$ = from.$field_$; )cc"); } @@ -192,39 +192,42 @@ void SingularPrimitive::GenerateInlineAccessorDefinitions( // @@protoc_insertion_point(field_get:$pkg.Msg.field$) return _internal_$name$(); } - inline void $Msg$::set_$name$($Type$ value) { - $PrepareSplitMessageForWrite$; - _internal_set_$name$(value); - $annotate_set$; - // @@protoc_insertion_point(field_set:$pkg.Msg.field$) - } )cc"); if (is_oneof()) { p->Emit(R"cc( - inline $Type$ $Msg$::_internal_$name$() const { - if ($has_field$) { - return $field_$; - } - return $kDefault$; - } - inline void $Msg$::_internal_set_$name$($Type$ value) { + inline void $Msg$::set_$name$($Type$ value) { + $PrepareSplitMessageForWrite$; if ($not_has_field$) { clear_$oneof_name$(); set_has_$name$(); } $field_$ = value; + $annotate_set$; + // @@protoc_insertion_point(field_set:$pkg.Msg.field$) + } + inline $Type$ $Msg$::_internal_$name$() const { + if ($has_field$) { + return $field_$; + } + return $kDefault$; } )cc"); } else { p->Emit(R"cc( + inline void $Msg$::set_$name$($Type$ value) { + $PrepareSplitMessageForWrite$; + _internal_set_$name$(value); + $set_hasbit$; + $annotate_set$; + // @@protoc_insertion_point(field_set:$pkg.Msg.field$) + } inline $Type$ $Msg$::_internal_$name$() const { $TsanDetectConcurrentRead$; return $field_$; } inline void $Msg$::_internal_set_$name$($Type$ value) { $TsanDetectConcurrentMutation$; - $set_hasbit$; $field_$ = value; } )cc"); diff --git a/src/google/protobuf/compiler/cpp/field_generators/string_field.cc b/src/google/protobuf/compiler/cpp/field_generators/string_field.cc index 426833da15..7464d81a2b 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/string_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/string_field.cc @@ -88,10 +88,27 @@ class SingularString : public FieldGeneratorBase { )cc"); } + bool RequiresArena(GeneratorFunction function) const override { + switch (function) { + case GeneratorFunction::kMergeFrom: + return is_oneof(); + } + return false; + } + void GenerateMergingCode(io::Printer* p) const override { - p->Emit(R"cc( - _this->_internal_set_$name$(from._internal_$name$()); - )cc"); + if (is_oneof()) { + p->Emit(R"cc( + if (oneof_needs_init) { + _this->$field_$.InitDefault(); + } + _this->$field_$.Set(from._internal_$name$(), arena); + )cc"); + } else { + p->Emit(R"cc( + _this->_internal_set_$name$(from._internal_$name$()); + )cc"); + } } void GenerateArenaDestructorCode(io::Printer* p) const override { diff --git a/src/google/protobuf/compiler/cpp/file.cc b/src/google/protobuf/compiler/cpp/file.cc index 1c88b8a226..65fc75c884 100644 --- a/src/google/protobuf/compiler/cpp/file.cc +++ b/src/google/protobuf/compiler/cpp/file.cc @@ -88,154 +88,6 @@ void UnmuteWuninitialized(io::Printer* p) { #endif // __llvm__ )"); } - -// TopologicalSortMessagesInFile topologically sorts and returns a vector of -// proto descriptors defined in the file provided as input. The underlying -// graph is defined using dependency relationship between protos. For example, -// if proto A contains proto B as a member, then proto B would be ordered before -// proto A in a topological ordering, assuming there is no mutual dependence -// between the two protos. The topological order is used to emit proto -// declarations so that a proto is declared after all the protos it is dependent -// on have been declared (again assuming no mutual dependence). This is needed -// in cases where we may declare proto B as a member of proto A using an object, -// instead of a pointer. -// -// The proto dependency graph can have cycles. So instead of directly working -// with protos, we compute strong connected components (SCCs) composed of protos -// with mutual dependence. The dependency graph on SCCs is a directed acyclic -// graph (DAG) and therefore a topological order can be computed for it i.e. an -// order where an SCC is ordered after all other SCCs it is dependent on have -// been ordered. -// -// The function below first constructs the SCC graph and then computes a -// deterministic topological order for the graph. -// -// For computing the SCC graph, we follow the following steps: -// 1. Collect the descriptors for the messages in the file. -// 2. Construct a map for descriptor to SCC mapping. -// 3. Construct a map for dependence between SCCs, referred to as -// child_to_parent_scc_map below. This map constructed by running a BFS on the -// SCCs. -// -// For computing a deterministic topological order on the graph computed in step -// 3 above, we do the following: -// 1. Since the graph on SCCs is a DAG, therefore there will be at least one SCC -// that does not depend on other SCCs. We first construct a list of all such -// SCCs. -// 2. Next we run a BFS starting with the list of SCCs computed in step 1. For -// each SCC, we track the number of the SCC it is dependent on and the number of -// those SCC that have been ordered. Once all the SCCs an SCC is dependent on -// have been ordered, this SCC is added to list of SCCs that are to be ordered -// next. -// 3. Within an SCC, the descriptors are ordered on the basis of the full_name() -// of the descriptors. -std::vector TopologicalSortMessagesInFile( - const FileDescriptor* file, MessageSCCAnalyzer& scc_analyzer) { - // Collect the messages defined in this file. - std::vector messages_in_file = FlattenMessagesInFile(file); - if (messages_in_file.empty()) return {}; - // Populate the map from the descriptor to the SCC to which the descriptor - // belongs. - absl::flat_hash_map descriptor_to_scc_map; - descriptor_to_scc_map.reserve(messages_in_file.size()); - for (const Descriptor* d : messages_in_file) { - descriptor_to_scc_map.emplace(d, scc_analyzer.GetSCC(d)); - } - ABSL_DCHECK(messages_in_file.size() == descriptor_to_scc_map.size()) - << "messages_in_file has duplicate messages!"; - // Each parent SCC has information about the child SCCs i.e. SCCs for fields - // that are contained in the protos that belong to the parent SCC. Use this - // information to construct the inverse map from child SCC to parent SCC. - absl::flat_hash_map> - child_to_parent_scc_map; - // For recording the number of edges from each SCC to other SCCs in the - // forward map. - absl::flat_hash_map scc_to_outgoing_edges_map; - std::queue sccs_to_process; - for (const auto& p : descriptor_to_scc_map) { - sccs_to_process.push(p.second); - } - // Run a BFS to fill the two data structures: child_to_parent_scc_map and - // scc_to_outgoing_edges_map. - while (!sccs_to_process.empty()) { - const SCC* scc = sccs_to_process.front(); - sccs_to_process.pop(); - auto& count = scc_to_outgoing_edges_map[scc]; - for (const auto& child : scc->children) { - // Test whether this child has been seen thus far. We do not know if the - // children SCC vector contains unique children SCC. - auto& parent_set = child_to_parent_scc_map[child]; - if (parent_set.empty()) { - // Just added. - sccs_to_process.push(child); - } - auto ret = parent_set.insert(scc); - if (ret.second) { - ++count; - } - } - } - std::vector next_scc_q; - // Find out the SCCs that do not have an outgoing edge i.e. the protos in this - // SCC do not depend on protos other than the ones in this SCC. - for (const auto& p : scc_to_outgoing_edges_map) { - if (p.second == 0) { - next_scc_q.push_back(p.first); - } - } - ABSL_DCHECK(!next_scc_q.empty()) << "No independent components!"; - // Topologically sort the SCCs. - // If an SCC no longer has an outgoing edge i.e. all the SCCs it depends on - // have been ordered, then this SCC is now a candidate for ordering. - std::vector sorted_messages; - while (!next_scc_q.empty()) { - std::vector current_scc_q; - current_scc_q.swap(next_scc_q); - // SCCs present in the current_scc_q are topologically equivalent to each - // other. Therefore they can be added to the output in any order. We sort - // these SCCs by the full_name() of the first descriptor that belongs to the - // SCC. This works well since the descriptors in each SCC are sorted by - // full_name() and also that a descriptor can be part of only one SCC. - std::sort(current_scc_q.begin(), current_scc_q.end(), - [](const SCC* a, const SCC* b) { - ABSL_DCHECK(!a->descriptors.empty()) << "No descriptors!"; - ABSL_DCHECK(!b->descriptors.empty()) << "No descriptors!"; - const Descriptor* ad = a->descriptors[0]; - const Descriptor* bd = b->descriptors[0]; - return ad->full_name() < bd->full_name(); - }); - while (!current_scc_q.empty()) { - const SCC* scc = current_scc_q.back(); - current_scc_q.pop_back(); - // Messages in an SCC are already sorted on full_name(). So we can emit - // them right away. - for (const Descriptor* d : scc->descriptors) { - // Only push messages that are defined in the file. - if (descriptor_to_scc_map.contains(d)) { - sorted_messages.push_back(d); - } - } - // Find all the SCCs that are dependent on the current SCC. - const auto& parents = child_to_parent_scc_map.find(scc); - if (parents == child_to_parent_scc_map.end()) continue; - for (const SCC* parent : parents->second) { - auto it = scc_to_outgoing_edges_map.find(parent); - ABSL_CHECK(it != scc_to_outgoing_edges_map.end()); - ABSL_CHECK(it->second > 0); - // Reduce the dependency count for the SCC. In case the dependency - // count reaches 0, add the SCC to the list of SCCs to be ordered next. - it->second--; - if (it->second == 0) { - next_scc_q.push_back(parent); - } - } - } - } - for (const auto& p : scc_to_outgoing_edges_map) { - ABSL_DCHECK(p.second == 0) << "SCC left behind!"; - } - return sorted_messages; -} } // namespace bool FileGenerator::ShouldSkipDependencyImports( @@ -611,11 +463,16 @@ void FileGenerator::GenerateSourceIncludes(io::Printer* p) { } absl::StrAppend(&target_basename, options_.proto_h ? ".proto.h" : ".pb.h"); + p->Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n"); + if (options_.opensource_runtime) { + p->Print("// Protobuf C++ Version: $protobuf_cpp_version$\n", + "protobuf_cpp_version", PROTOBUF_CPP_VERSION_STRING); + } + p->Print("\n"); p->Emit({{"h_include", CreateHeaderInclude(target_basename, file_)}}, R"( - // Generated by the protocol buffer compiler. DO NOT EDIT! - // source: $filename$ - #include $h_include$ #include @@ -952,6 +809,23 @@ void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* p) { )cc"); } +void FileGenerator::GenerateStaticInitializer(io::Printer* p) { + if (static_initializers_.empty()) return; + p->Emit({{"expr", + [&] { + for (auto& init : static_initializers_) { + init(p); + } + }}}, + R"cc( + PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 + static ::std::false_type _static_init_ PROTOBUF_UNUSED = + ($expr$, ::std::false_type{}); + )cc"); + // Reset the vector because we might be generating many files. + static_initializers_.clear(); +} + void FileGenerator::GenerateSourceForExtension(int idx, io::Printer* p) { auto v = p->WithVars(FileVars(file_, options_)); GenerateSourceIncludes(p); @@ -959,6 +833,10 @@ void FileGenerator::GenerateSourceForExtension(int idx, io::Printer* p) { NamespaceOpener ns(Namespace(file_, options_), p); extension_generators_[idx]->GenerateDefinition(p); + static_initializers_.push_back([this, idx](auto* p) { + extension_generators_[idx]->GenerateRegistration(p); + }); + GenerateStaticInitializer(p); } void FileGenerator::GenerateGlobalSource(io::Printer* p) { @@ -1038,8 +916,14 @@ void FileGenerator::GenerateSource(io::Printer* p) { } // Define extensions. + const auto is_lazily_init = IsLazilyInitializedFile(file_->name()); for (int i = 0; i < extension_generators_.size(); ++i) { extension_generators_[i]->GenerateDefinition(p); + if (!is_lazily_init) { + static_initializers_.push_back([&, i](auto* p) { + extension_generators_[i]->GenerateRegistration(p); + }); + } } p->Emit(R"cc( @@ -1062,9 +946,31 @@ void FileGenerator::GenerateSource(io::Printer* p) { UnmuteWuninitialized(p); } + GenerateStaticInitializer(p); + IncludeFile("third_party/protobuf/port_undef.inc", p); } +static std::vector +GetMessagesToPinGloballyForWeakDescriptors(const FileDescriptor* file) { + std::vector out; + + // For simplicity we force pin request/response messages for all + // services. The current implementation of services might not do + // the pin itself, so it is simpler. + // This is a place for improvement in the future. + for (int i = 0; i < file->service_count(); ++i) { + auto* service = file->service(i); + for (int j = 0; j < service->method_count(); ++j) { + auto* method = service->method(j); + out.push_back(method->input_type()); + out.push_back(method->output_type()); + } + } + + return out; +} + void FileGenerator::GenerateReflectionInitializationCode(io::Printer* p) { if (!message_generators_.empty()) { p->Emit({{"len", message_generators_.size()}}, R"cc( @@ -1098,6 +1004,8 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* p) { if (!message_generators_.empty()) { std::vector> offsets; offsets.reserve(message_generators_.size()); + bool has_implicit_weak_descriptors = + UsingImplicitWeakDescriptor(file_, options_); p->Emit( { @@ -1116,19 +1024,50 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* p) { offset += offsets[i].first; } }}, - {"defaults", + {"weak_defaults", [&] { + if (!has_implicit_weak_descriptors) return; + int index = 0; for (auto& gen : message_generators_) { p->Emit( { + {"index", index++}, {"ns", Namespace(gen->descriptor(), options_)}, {"class", ClassName(gen->descriptor())}, + {"section", WeakDefaultWriterSection(gen->descriptor(), + options_)}, }, R"cc( - &$ns$::_$class$_default_instance_._instance, + constexpr ::_pbi::WeakDefaultWriter pb_$index$_weak_ + __attribute__((__nodebug__)) + __attribute__((section("$section$"))) = { + file_default_instances + $index$, + &$ns$::_$class$_default_instance_._instance}; )cc"); } }}, + {"defaults", + [&] { + for (auto& gen : message_generators_) { + if (has_implicit_weak_descriptors) { + p->Emit(R"cc( + nullptr, + )cc"); + } else { + p->Emit( + { + {"ns", Namespace(gen->descriptor(), options_)}, + {"class", ClassName(gen->descriptor())}, + }, + R"cc( + &$ns$::_$class$_default_instance_._instance, + )cc"); + } + } + }}, + // When we have implicit weak descriptors we make the array mutable + // for dynamic initialization. + {"const", has_implicit_weak_descriptors ? "" : "const"}, }, R"cc( const ::uint32_t @@ -1142,9 +1081,10 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* p) { $schemas$, }; - static const ::_pb::Message* const file_default_instances[] = { + static const ::_pb::Message* $const $file_default_instances[] = { $defaults$, }; + $weak_defaults$; )cc"); } else { // Ee still need these symbols to exist. @@ -1312,12 +1252,24 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* p) { // pull in a lot of unnecessary code that can't be stripped by --gc-sections. // Descriptor initialization will still be performed lazily when it's needed. if (!IsLazilyInitializedFile(file_->name())) { - p->Emit({{"dummy", UniqueName("dynamic_init_dummy", file_, options_)}}, - R"cc( - // Force running AddDescriptors() at dynamic initialization time. - PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 - static ::_pbi::AddDescriptorsRunner $dummy$(&$desc_table$); - )cc"); + if (UsingImplicitWeakDescriptor(file_, options_)) { + for (auto* pinned : GetMessagesToPinGloballyForWeakDescriptors(file_)) { + static_initializers_.push_back([this, pinned](auto* p) { + p->Emit( + { + {"default", QualifiedDefaultInstanceName(pinned, options_)}, + }, + R"cc( + ::_pbi::StrongPointer(&$default$), + )cc"); + }); + } + } + static_initializers_.push_back([](auto* p) { + p->Emit(R"cc( + ::_pbi::AddDescriptors(&$desc_table$), + )cc"); + }); } // However, we must provide a way to force initialize the default instances @@ -1405,14 +1357,12 @@ class FileGenerator::ForwardDeclarations { // However, it increases the size of the pb.cc translation units so it // is a tradeoff. p->Emit({{"class", QualifiedClassName(c.second, options)}}, R"cc( - template <> - $dllexport_decl $$class$* Arena::CreateMaybeMessage<$class$>(Arena*); + extern template void* Arena::DefaultConstruct<$class$>(Arena*); )cc"); if (!IsMapEntryMessage(c.second)) { p->Emit({{"class", QualifiedClassName(c.second, options)}}, R"cc( - template <> - $dllexport_decl $$class$* Arena::CreateMaybeMessage<$class$>( - Arena*, const $class$&); + extern template void* Arena::CopyConstruct<$class$>(Arena*, + const void*); )cc"); } } @@ -1520,21 +1470,14 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* p) { IncludeFile("third_party/protobuf/port_def.inc", p); p->Emit( { - {"min_version", PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC}, {"version", PROTOBUF_VERSION}, }, R"( - #if PROTOBUF_VERSION < $min_version$ - #error "This file was generated by a newer version of protoc which is" - #error "incompatible with your Protocol Buffer headers. Please update" - #error "your headers." - #endif // PROTOBUF_VERSION - - #if $version$ < PROTOBUF_MIN_PROTOC_VERSION - #error "This file was generated by an older version of protoc which is" - #error "incompatible with your Protocol Buffer headers. Please" - #error "regenerate this file with a newer version of protoc." - #endif // PROTOBUF_MIN_PROTOC_VERSION + #if PROTOBUF_VERSION != $version$ + #error "Protobuf C++ gencode is built with an incompatible version of" + #error "Protobuf C++ headers/runtime. See" + #error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp" + #endif )"); IncludeFile("third_party/protobuf/port_undef.inc", p); } diff --git a/src/google/protobuf/compiler/cpp/file.h b/src/google/protobuf/compiler/cpp/file.h index 02f581d8e2..8388207b15 100644 --- a/src/google/protobuf/compiler/cpp/file.h +++ b/src/google/protobuf/compiler/cpp/file.h @@ -19,6 +19,7 @@ #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" +#include "absl/functional/any_invocable.h" #include "absl/log/absl_check.h" #include "google/protobuf/compiler/cpp/enum.h" #include "google/protobuf/compiler/cpp/extension.h" @@ -78,6 +79,11 @@ class PROTOC_EXPORT FileGenerator { void GenerateFile(io::Printer* p, GeneratedFileType file_type, std::function cb); + // Generates a static initializers with all the existing values from + // `static_initializers_`. + // They run in `PROTOBUF_ATTRIBUTE_INIT_PRIORITY2` priority. + void GenerateStaticInitializer(io::Printer* p); + // Shared code between the two header generators. void GenerateSharedHeaderCode(io::Printer* p); @@ -170,6 +176,8 @@ class PROTOC_EXPORT FileGenerator { absl::flat_hash_set weak_deps_; + std::vector> static_initializers_; + const FileDescriptor* file_; Options options_; diff --git a/src/google/protobuf/compiler/cpp/generator.cc b/src/google/protobuf/compiler/cpp/generator.cc index cc0f8af090..ac0f9828d9 100644 --- a/src/google/protobuf/compiler/cpp/generator.cc +++ b/src/google/protobuf/compiler/cpp/generator.cc @@ -17,15 +17,21 @@ #include #include +#include "absl/container/flat_hash_map.h" +#include "absl/log/absl_check.h" +#include "absl/memory/memory.h" #include "absl/status/status.h" #include "absl/strings/match.h" #include "absl/strings/str_cat.h" +#include "absl/strings/str_split.h" #include "absl/strings/string_view.h" #include "google/protobuf/compiler/cpp/file.h" #include "google/protobuf/compiler/cpp/helpers.h" +#include "google/protobuf/compiler/cpp/options.h" #include "google/protobuf/cpp_features.pb.h" #include "google/protobuf/descriptor.pb.h" #include "google/protobuf/descriptor_visitor.h" +#include "google/protobuf/io/printer.h" namespace google { @@ -139,6 +145,8 @@ bool CppGenerator::Generate(const FileDescriptor* file, if (!value.empty()) { file_options.num_cc_files = std::strtol(value.c_str(), nullptr, 10); } + } else if (key == "descriptor_implicit_weak_messages") { + file_options.descriptor_implicit_weak_messages = true; } else if (key == "proto_h") { file_options.proto_h = true; } else if (key == "proto_static_reflection_h") { diff --git a/src/google/protobuf/compiler/cpp/helpers.cc b/src/google/protobuf/compiler/cpp/helpers.cc index c14e064c57..79d47684d6 100644 --- a/src/google/protobuf/compiler/cpp/helpers.cc +++ b/src/google/protobuf/compiler/cpp/helpers.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -1024,6 +1025,13 @@ bool IsPresentMessage(const Descriptor* descriptor, const Options& options) { return true; } +const FieldDescriptor* FindHottestField( + const std::vector& fields, const Options& options) { + (void)fields; + (void)options; + return nullptr; +} + static bool HasRepeatedFields(const Descriptor* descriptor) { for (int i = 0; i < descriptor->field_count(); ++i) { if (descriptor->field(i)->label() == FieldDescriptor::LABEL_REPEATED) { @@ -1310,6 +1318,154 @@ void FlattenMessagesInFile(const FileDescriptor* file, } } +// TopologicalSortMessagesInFile topologically sorts and returns a vector of +// proto descriptors defined in the file provided as input. The underlying +// graph is defined using dependency relationship between protos. For example, +// if proto A contains proto B as a member, then proto B would be ordered before +// proto A in a topological ordering, assuming there is no mutual dependence +// between the two protos. The topological order is used to emit proto +// declarations so that a proto is declared after all the protos it is dependent +// on have been declared (again assuming no mutual dependence). This is needed +// in cases where we may declare proto B as a member of proto A using an object, +// instead of a pointer. +// +// The proto dependency graph can have cycles. So instead of directly working +// with protos, we compute strong connected components (SCCs) composed of protos +// with mutual dependence. The dependency graph on SCCs is a directed acyclic +// graph (DAG) and therefore a topological order can be computed for it i.e. an +// order where an SCC is ordered after all other SCCs it is dependent on have +// been ordered. +// +// The function below first constructs the SCC graph and then computes a +// deterministic topological order for the graph. +// +// For computing the SCC graph, we follow the following steps: +// 1. Collect the descriptors for the messages in the file. +// 2. Construct a map for descriptor to SCC mapping. +// 3. Construct a map for dependence between SCCs, referred to as +// child_to_parent_scc_map below. This map constructed by running a BFS on the +// SCCs. +// +// For computing a deterministic topological order on the graph computed in step +// 3 above, we do the following: +// 1. Since the graph on SCCs is a DAG, therefore there will be at least one SCC +// that does not depend on other SCCs. We first construct a list of all such +// SCCs. +// 2. Next we run a BFS starting with the list of SCCs computed in step 1. For +// each SCC, we track the number of the SCC it is dependent on and the number of +// those SCC that have been ordered. Once all the SCCs an SCC is dependent on +// have been ordered, this SCC is added to list of SCCs that are to be ordered +// next. +// 3. Within an SCC, the descriptors are ordered on the basis of the full_name() +// of the descriptors. +std::vector TopologicalSortMessagesInFile( + const FileDescriptor* file, MessageSCCAnalyzer& scc_analyzer) { + // Collect the messages defined in this file. + std::vector messages_in_file = FlattenMessagesInFile(file); + if (messages_in_file.empty()) return {}; + // Populate the map from the descriptor to the SCC to which the descriptor + // belongs. + absl::flat_hash_map descriptor_to_scc_map; + descriptor_to_scc_map.reserve(messages_in_file.size()); + for (const Descriptor* d : messages_in_file) { + descriptor_to_scc_map.emplace(d, scc_analyzer.GetSCC(d)); + } + ABSL_DCHECK(messages_in_file.size() == descriptor_to_scc_map.size()) + << "messages_in_file has duplicate messages!"; + // Each parent SCC has information about the child SCCs i.e. SCCs for fields + // that are contained in the protos that belong to the parent SCC. Use this + // information to construct the inverse map from child SCC to parent SCC. + absl::flat_hash_map> + child_to_parent_scc_map; + // For recording the number of edges from each SCC to other SCCs in the + // forward map. + absl::flat_hash_map scc_to_outgoing_edges_map; + std::queue sccs_to_process; + for (const auto& p : descriptor_to_scc_map) { + sccs_to_process.push(p.second); + } + // Run a BFS to fill the two data structures: child_to_parent_scc_map and + // scc_to_outgoing_edges_map. + while (!sccs_to_process.empty()) { + const SCC* scc = sccs_to_process.front(); + sccs_to_process.pop(); + auto& count = scc_to_outgoing_edges_map[scc]; + for (const auto& child : scc->children) { + // Test whether this child has been seen thus far. We do not know if the + // children SCC vector contains unique children SCC. + auto& parent_set = child_to_parent_scc_map[child]; + if (parent_set.empty()) { + // Just added. + sccs_to_process.push(child); + } + auto ret = parent_set.insert(scc); + if (ret.second) { + ++count; + } + } + } + std::vector next_scc_q; + // Find out the SCCs that do not have an outgoing edge i.e. the protos in this + // SCC do not depend on protos other than the ones in this SCC. + for (const auto& p : scc_to_outgoing_edges_map) { + if (p.second == 0) { + next_scc_q.push_back(p.first); + } + } + ABSL_DCHECK(!next_scc_q.empty()) << "No independent components!"; + // Topologically sort the SCCs. + // If an SCC no longer has an outgoing edge i.e. all the SCCs it depends on + // have been ordered, then this SCC is now a candidate for ordering. + std::vector sorted_messages; + while (!next_scc_q.empty()) { + std::vector current_scc_q; + current_scc_q.swap(next_scc_q); + // SCCs present in the current_scc_q are topologically equivalent to each + // other. Therefore they can be added to the output in any order. We sort + // these SCCs by the full_name() of the first descriptor that belongs to the + // SCC. This works well since the descriptors in each SCC are sorted by + // full_name() and also that a descriptor can be part of only one SCC. + std::sort(current_scc_q.begin(), current_scc_q.end(), + [](const SCC* a, const SCC* b) { + ABSL_DCHECK(!a->descriptors.empty()) << "No descriptors!"; + ABSL_DCHECK(!b->descriptors.empty()) << "No descriptors!"; + const Descriptor* ad = a->descriptors[0]; + const Descriptor* bd = b->descriptors[0]; + return ad->full_name() < bd->full_name(); + }); + while (!current_scc_q.empty()) { + const SCC* scc = current_scc_q.back(); + current_scc_q.pop_back(); + // Messages in an SCC are already sorted on full_name(). So we can emit + // them right away. + for (const Descriptor* d : scc->descriptors) { + // Only push messages that are defined in the file. + if (descriptor_to_scc_map.contains(d)) { + sorted_messages.push_back(d); + } + } + // Find all the SCCs that are dependent on the current SCC. + const auto& parents = child_to_parent_scc_map.find(scc); + if (parents == child_to_parent_scc_map.end()) continue; + for (const SCC* parent : parents->second) { + auto it = scc_to_outgoing_edges_map.find(parent); + ABSL_CHECK(it != scc_to_outgoing_edges_map.end()); + ABSL_CHECK(it->second > 0); + // Reduce the dependency count for the SCC. In case the dependency + // count reaches 0, add the SCC to the list of SCCs to be ordered next. + it->second--; + if (it->second == 0) { + next_scc_q.push_back(parent); + } + } + } + } + for (const auto& p : scc_to_outgoing_edges_map) { + ABSL_DCHECK(p.second == 0) << "SCC left behind!"; + } + return sorted_messages; +} + bool HasWeakFields(const Descriptor* descriptor, const Options& options) { for (int i = 0; i < descriptor->field_count(); i++) { if (IsWeak(descriptor->field(i), options)) return true; @@ -1324,6 +1480,32 @@ bool HasWeakFields(const FileDescriptor* file, const Options& options) { return false; } +bool UsingImplicitWeakDescriptor(const FileDescriptor* file, + const Options& options) { + return HasDescriptorMethods(file, options) && + !IsBootstrapProto(options, file) && + options.descriptor_implicit_weak_messages && + !options.opensource_runtime; +} + +std::string WeakDefaultWriterSection(const Descriptor* descriptor, + const Options& options) { + const auto* file = descriptor->file(); + + // To make a compact name we use the index of the object in its parent instead + // of its name, recursively until we reach the root. + // So the name could be `pb_def_1_2_1_0_HASH` instead of + // `pd_def_VeryLongClassName_WithNesting_AndMoreNames_HASH` + // We need a know common prefix to merge the sections later on. + std::string prefix = "pb_def"; + do { + absl::StrAppend(&prefix, "_", descriptor->index()); + descriptor = descriptor->containing_type(); + } while (descriptor != nullptr); + + return UniqueName(prefix, file, options); +} + bool UsingImplicitWeakFields(const FileDescriptor* file, const Options& options) { return options.lite_implicit_weak_fields && diff --git a/src/google/protobuf/compiler/cpp/helpers.h b/src/google/protobuf/compiler/cpp/helpers.h index 4c590cdc76..64e2a82aa4 100644 --- a/src/google/protobuf/compiler/cpp/helpers.h +++ b/src/google/protobuf/compiler/cpp/helpers.h @@ -15,6 +15,7 @@ #include #include #include +#include #include "absl/container/flat_hash_map.h" #include "absl/log/absl_check.h" @@ -429,6 +430,10 @@ bool ShouldForceAllocationOnConstruction(const Descriptor* desc, // Returns true if the message is present based on PDProto profile. bool IsPresentMessage(const Descriptor* descriptor, const Options& options); +// Returns the most likely present field. Returns nullptr if not profile driven. +const FieldDescriptor* FindHottestField( + const std::vector& fields, const Options& options); + // Does the file contain any definitions that need extension_set.h? bool HasExtensionsOrExtendableMessage(const FileDescriptor* file); @@ -624,6 +629,9 @@ inline std::vector FlattenMessagesInFile( return result; } +std::vector TopologicalSortMessagesInFile( + const FileDescriptor* file, MessageSCCAnalyzer& scc_analyzer); + template void ForEachMessage(const Descriptor* descriptor, F&& func) { for (int i = 0; i < descriptor->nested_type_count(); i++) @@ -726,6 +734,64 @@ void ForEachField(const FileDescriptor* d, T&& func) { void ListAllTypesForServices(const FileDescriptor* fd, std::vector* types); +// Whether this type should use the implicit weak feature for descriptor based +// objects. +// +// This feature allows tree shaking within a single translation unit by +// decoupling the messages from the TU-wide `file_default_instances` array. +// This way there are no static initializers in the TU pointing to any part of +// the generated classes and they can be GC'd by the linker. +// Instead, we inject the surviving messages by having `WeakDefaultWriter` +// objects in a special `pb_defaults` section. The runtime will iterate this +// section to see the list of all live objects and put them back into the +// `file_default_instances` array. +// +// Any object that gets GC'd will have a `nullptr` in the respective slot in the +// `file_default_instances` array. The runtime will recognize this and will +// dynamically generate the object if needed. This logic is in the +// `GeneratedMessageFactory::GetPrototype`. It will fall back to a +// `DynamicMessage` for the missing objects. +// This allows all of reflection to keep working normally, even for types that +// were dropped. Note that dropping the _classes_ will not drop the descriptor +// information. The messages are still going to be registered in the generated +// `DescriptorPool` and will be available via normal `FindMessageTypeByName` and +// friends. +// +// A "pin" is adding dependency edge in the graph for the GC. +// The `WeakDefaultWriter`, the default instance, and vtable of a message all +// pin each other. If anyone lives, they all do. This is important. +// The `WeakDefaultWriter` pins the default instance of the message by using it. +// The default instance of the message pins the vtable trivially by using it. +// The vtable pins the `WeakDefaultWriter` by having a StrongPointer into it +// from any of the virtual functions. +// +// All parent messages pin their children. +// SPEED messages do this implicitly via the TcParseTable, which contain +// pointers to the submessages. +// CODE_SIZE messages explicitly add a pin via `StrongPointer` somewhere in +// their codegen. +// LITE messages do not participate at all in this feature. +// +// For extensions, the identifiers currently pin the extendee. The extended is +// assumed to by pinned elsewhere since we already have an instance of it when +// we call `.GetExtension` et al. The extension identifier itself is not +// automatically pinned, so it has to be used to participate in the graph. +// Registration of the extensions do not pin the extended or the extendee. At +// registration time we will eagerly create a prototype object if one is +// missing to insert in the extension table in ExtensionSet. +// +// For services, the TU unconditionally pins the request/response objects. +// This is the status quo for simplicitly to avoid modifying the RPC layer. It +// might be improved in the future. +bool UsingImplicitWeakDescriptor(const FileDescriptor* file, + const Options& options); + +// Section name to be used for the DefaultWriter object for implicit weak +// descriptor objects. +// See `UsingImplicitWeakDescriptor` above. +std::string WeakDefaultWriterSection(const Descriptor* descriptor, + const Options& options); + // Indicates whether we should use implicit weak fields for this file. bool UsingImplicitWeakFields(const FileDescriptor* file, const Options& options); diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index b5f89a9da2..765935ae8e 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -37,6 +38,7 @@ #include "google/protobuf/compiler/cpp/field.h" #include "google/protobuf/compiler/cpp/helpers.h" #include "google/protobuf/compiler/cpp/names.h" +#include "google/protobuf/compiler/cpp/options.h" #include "google/protobuf/compiler/cpp/padding_optimizer.h" #include "google/protobuf/compiler/cpp/parse_function_generator.h" #include "google/protobuf/compiler/cpp/tracker.h" @@ -657,76 +659,75 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* p) { auto v = p->WithVars(FieldVars(field, options_)); auto t = p->WithVars(MakeTrackerCalls(field, options_)); - p->Emit( - {{"field_comment", FieldComment(field, options_)}, - Sub("const_impl", "const;").WithSuffix(";"), - Sub("impl", ";").WithSuffix(";"), - {"sizer", - [&] { - if (!field->is_repeated()) return; - p->Emit({Sub("name_size", absl::StrCat(name, "_size")) - .AnnotatedAs(field)}, - R"cc( - $deprecated_attr $int $name_size$() $const_impl$; - )cc"); + p->Emit({{"field_comment", FieldComment(field, options_)}, + Sub("const_impl", "const;").WithSuffix(";"), + Sub("impl", ";").WithSuffix(";"), + {"sizer", + [&] { + if (!field->is_repeated()) return; + p->Emit({Sub("name_size", absl::StrCat(name, "_size")) + .AnnotatedAs(field)}, + R"cc( + $deprecated_attr $int $name_size$() $const_impl$; + )cc"); - p->Emit({Sub("_internal_name_size", - absl::StrCat("_internal_", name, "_size")) - .AnnotatedAs(field)}, - R"cc( - private: - int $_internal_name_size$() const; + p->Emit({Sub("_internal_name_size", + absl::StrCat("_internal_", name, "_size")) + .AnnotatedAs(field)}, + R"cc( + private: + int $_internal_name_size$() const; - public: - )cc"); - }}, - {"hazzer", - [&] { - if (!field->has_presence()) return; - p->Emit({Sub("has_name", absl::StrCat("has_", name)) - .AnnotatedAs(field)}, - R"cc( - $deprecated_attr $bool $has_name$() $const_impl$; - )cc"); - }}, - {"internal_hazzer", - [&] { - if (field->is_repeated() || !HasInternalHasMethod(field)) { - return; - } - p->Emit( - {Sub("_internal_has_name", absl::StrCat("_internal_has_", name)) - .AnnotatedAs(field)}, - R"cc( - private: - bool $_internal_has_name$() const; + public: + )cc"); + }}, + {"hazzer", + [&] { + if (!field->has_presence()) return; + p->Emit({Sub("has_name", absl::StrCat("has_", name)) + .AnnotatedAs(field)}, + R"cc( + $deprecated_attr $bool $has_name$() $const_impl$; + )cc"); + }}, + {"internal_hazzer", + [&] { + if (field->is_repeated() || !HasInternalHasMethod(field)) { + return; + } + p->Emit({Sub("_internal_has_name", + absl::StrCat("_internal_has_", name)) + .AnnotatedAs(field)}, + R"cc( + private: + bool $_internal_has_name$() const; - public: - )cc"); - }}, - {"clearer", - [&] { - p->Emit({Sub("clear_name", absl::StrCat("clear_", name)) - .AnnotatedAs({ - field, - Semantic::kSet, - })}, - R"cc( - $deprecated_attr $void $clear_name$() $impl$; - )cc"); - }}, - {"accessors", - [&] { - field_generators_.get(field).GenerateAccessorDeclarations(p); - }}}, - R"cc( - // $field_comment$ - $sizer$; - $hazzer$; - $internal_hazzer$; - $clearer$; - $accessors$; - )cc"); + public: + )cc"); + }}, + {"clearer", + [&] { + p->Emit({Sub("clear_name", absl::StrCat("clear_", name)) + .AnnotatedAs({ + field, + Semantic::kSet, + })}, + R"cc( + $deprecated_attr $void $clear_name$() $impl$; + )cc"); + }}, + {"accessors", + [&] { + field_generators_.get(field).GenerateAccessorDeclarations(p); + }}}, + R"cc( + // $field_comment$ + $sizer$; + $hazzer$; + $internal_hazzer$; + $clearer$; + $accessors$; + )cc"); } if (descriptor_->extension_range_count() > 0) { @@ -1155,725 +1156,848 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* p) { GenerateOneofHasBits(p); } -void MessageGenerator::GenerateClassDefinition(io::Printer* p) { - if (!ShouldGenerateClass(descriptor_, options_)) return; - - auto v = p->WithVars(ClassVars(descriptor_, options_)); - auto t = p->WithVars(MakeTrackerCalls(descriptor_, options_)); +void MessageGenerator::GenerateMapEntryClassDefinition(io::Printer* p) { Formatter format(p); - - if (IsMapEntryMessage(descriptor_)) { - absl::flat_hash_map vars; - CollectMapInfo(options_, descriptor_, &vars); - vars["lite"] = - HasDescriptorMethods(descriptor_->file(), options_) ? "" : "Lite"; - auto v = p->WithVars(std::move(vars)); - // Templatize constexpr constructor as a workaround for a bug in gcc 12 - // (warning in gcc 13). - p->Emit(R"cc( - class $classname$ final - : public ::$proto_ns$::internal::MapEntry$lite$< - $classname$, $key_cpp$, $val_cpp$, - ::$proto_ns$::internal::WireFormatLite::$key_wire_type$, - ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> { - public: - using SuperType = ::$proto_ns$::internal::MapEntry$lite$< - $classname$, $key_cpp$, $val_cpp$, - ::$proto_ns$::internal::WireFormatLite::$key_wire_type$, - ::$proto_ns$::internal::WireFormatLite::$val_wire_type$>; - $classname$(); - template - explicit PROTOBUF_CONSTEXPR $classname$( - ::$proto_ns$::internal::ConstantInitialized); - explicit $classname$(::$proto_ns$::Arena* arena); - static const $classname$* internal_default_instance() { - return reinterpret_cast( - &_$classname$_default_instance_); - } - )cc"); - auto utf8_check = internal::cpp::GetUtf8CheckMode( - descriptor_->field(0), GetOptimizeFor(descriptor_->file(), options_) == - FileOptions::LITE_RUNTIME); - if (descriptor_->field(0)->type() == FieldDescriptor::TYPE_STRING && - utf8_check != Utf8CheckMode::kNone) { - if (utf8_check == Utf8CheckMode::kStrict) { - format( - " static bool ValidateKey(std::string* s) {\n" - " return ::$proto_ns$::internal::WireFormatLite::" - "VerifyUtf8String(s->data(), static_cast(s->size()), " - "::$proto_ns$::internal::WireFormatLite::PARSE, \"$1$\");\n" - " }\n", - descriptor_->field(0)->full_name()); - } else { - ABSL_CHECK(utf8_check == Utf8CheckMode::kVerify); - format( - " static bool ValidateKey(std::string* s) {\n" - "#ifndef NDEBUG\n" - " ::$proto_ns$::internal::WireFormatLite::VerifyUtf8String(\n" - " s->data(), static_cast(s->size()), " - "::$proto_ns$::internal::" - "WireFormatLite::PARSE, \"$1$\");\n" - "#else\n" - " (void) s;\n" - "#endif\n" - " return true;\n" - " }\n", - descriptor_->field(0)->full_name()); - } - } else { - format(" static bool ValidateKey(void*) { return true; }\n"); - } - if (descriptor_->field(1)->type() == FieldDescriptor::TYPE_STRING && - utf8_check != Utf8CheckMode::kNone) { - if (utf8_check == Utf8CheckMode::kStrict) { - format( - " static bool ValidateValue(std::string* s) {\n" - " return ::$proto_ns$::internal::WireFormatLite::" - "VerifyUtf8String(s->data(), static_cast(s->size()), " - "::$proto_ns$::internal::WireFormatLite::PARSE, \"$1$\");\n" - " }\n", - descriptor_->field(1)->full_name()); - } else { - ABSL_CHECK(utf8_check == Utf8CheckMode::kVerify); - format( - " static bool ValidateValue(std::string* s) {\n" - "#ifndef NDEBUG\n" - " ::$proto_ns$::internal::WireFormatLite::VerifyUtf8String(\n" - " s->data(), static_cast(s->size()), " - "::$proto_ns$::internal::" - "WireFormatLite::PARSE, \"$1$\");\n" - "#else\n" - " (void) s;\n" - "#endif\n" - " return true;\n" - " }\n", - descriptor_->field(1)->full_name()); - } - } else { - format(" static bool ValidateValue(void*) { return true; }\n"); - } - if (HasDescriptorMethods(descriptor_->file(), options_)) { - format( - " ::$proto_ns$::Metadata GetMetadata() const final;\n"); - } - format( - " friend struct ::$tablename$;\n" - "};\n"); - return; - } - - format( - "class $dllexport_decl $${1$$classname$$}$ final :\n" - " public $superclass$ /* @@protoc_insertion_point(" - "class_definition:$full_name$) */ {\n", - descriptor_); - format(" public:\n"); - format.Indent(); - - format("inline $classname$() : $classname$(nullptr) {}\n"); - if (!HasSimpleBaseClass(descriptor_, options_)) { - format("~$classname$() override;\n"); - } - format( - // Templatize constexpr constructor as a workaround for a bug in gcc 12 - // (warning in gcc 13). - "template\n" - "explicit PROTOBUF_CONSTEXPR " - "$classname$(::$proto_ns$::internal::ConstantInitialized);\n" - "\n" - "inline $classname$(const $classname$& from)\n" - " : $classname$(nullptr, from) {}\n" - "$classname$($classname$&& from) noexcept\n" - " : $classname$() {\n" - " *this = ::std::move(from);\n" - "}\n" - "\n" - "inline $classname$& operator=(const $classname$& from) {\n" - " CopyFrom(from);\n" - " return *this;\n" - "}\n" - "inline $classname$& operator=($classname$&& from) noexcept {\n" - " if (this == &from) return *this;\n" - " if (GetArena() == from.GetArena()\n" - "#ifdef PROTOBUF_FORCE_COPY_IN_MOVE\n" - " && GetArena() != nullptr\n" - "#endif // !PROTOBUF_FORCE_COPY_IN_MOVE\n" - " ) {\n" - " InternalSwap(&from);\n" - " } else {\n" - " CopyFrom(from);\n" - " }\n" - " return *this;\n" - "}\n" - "\n"); - + absl::flat_hash_map vars; + CollectMapInfo(options_, descriptor_, &vars); + ABSL_CHECK(HasDescriptorMethods(descriptor_->file(), options_)); + auto v = p->WithVars(std::move(vars)); + // Templatize constexpr constructor as a workaround for a bug in gcc 12 + // (warning in gcc 13). p->Emit(R"cc( - inline const $unknown_fields_type$& unknown_fields() const - ABSL_ATTRIBUTE_LIFETIME_BOUND { - $annotate_unknown_fields$; - return $unknown_fields$; - } - inline $unknown_fields_type$* mutable_unknown_fields() - ABSL_ATTRIBUTE_LIFETIME_BOUND { - $annotate_mutable_unknown_fields$; - return $mutable_unknown_fields$; - } + class $classname$ final + : public ::$proto_ns$::internal::MapEntry< + $classname$, $key_cpp$, $val_cpp$, + ::$proto_ns$::internal::WireFormatLite::$key_wire_type$, + ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> { + public: + using SuperType = ::$proto_ns$::internal::MapEntry< + $classname$, $key_cpp$, $val_cpp$, + ::$proto_ns$::internal::WireFormatLite::$key_wire_type$, + ::$proto_ns$::internal::WireFormatLite::$val_wire_type$>; + $classname$(); + template + explicit PROTOBUF_CONSTEXPR $classname$( + ::$proto_ns$::internal::ConstantInitialized); + explicit $classname$(::$proto_ns$::Arena* arena); + static const $classname$* internal_default_instance() { + return reinterpret_cast( + &_$classname$_default_instance_); + } )cc"); - // Adding a blank line to be consistent with the previous version. - p->Emit("\n"); - - // Only generate this member if it's not disabled. - if (HasDescriptorMethods(descriptor_->file(), options_) && - !descriptor_->options().no_standard_descriptor_accessor()) { - format( - "static const ::$proto_ns$::Descriptor* descriptor() {\n" - " return GetDescriptor();\n" - "}\n"); - } - - if (HasDescriptorMethods(descriptor_->file(), options_)) { - // These shadow non-static methods of the same names in Message. We - // redefine them here because calls directly on the generated class can be - // statically analyzed -- we know what descriptor types are being requested. - // It also avoids a vtable dispatch. - // - // We would eventually like to eliminate the methods in Message, and having - // this separate also lets us track calls to the base class methods - // separately. - format( - "static const ::$proto_ns$::Descriptor* GetDescriptor() {\n" - " return default_instance().GetMetadata().descriptor;\n" - "}\n" - "static const ::$proto_ns$::Reflection* GetReflection() {\n" - " return default_instance().GetMetadata().reflection;\n" - "}\n"); - } - - format( - "static const $classname$& default_instance() {\n" - " return *internal_default_instance();\n" - "}\n"); - - // Generate enum values for every field in oneofs. One list is generated for - // each oneof with an additional *_NOT_SET value. - for (auto oneof : OneOfRange(descriptor_)) { - format("enum $1$Case {\n", UnderscoresToCamelCase(oneof->name(), true)); - format.Indent(); - for (auto field : FieldRange(oneof)) { - format("$1$ = $2$,\n", OneofCaseConstantName(field), // 1 - field->number()); // 2 - } - format("$1$_NOT_SET = 0,\n", absl::AsciiStrToUpper(oneof->name())); - format.Outdent(); - format( - "};\n" - "\n"); - } - - // TODO make this private, while still granting other protos access. - format( - "static inline const $classname$* internal_default_instance() {\n" - " return reinterpret_cast(\n" - " &_$classname$_default_instance_);\n" - "}\n" - "static constexpr int kIndexInFileMessages =\n" - " $1$;\n" - "\n", - index_in_file_messages_); - - if (IsAnyMessage(descriptor_)) { - format( - "// implements Any -----------------------------------------------\n" - "\n"); - if (HasDescriptorMethods(descriptor_->file(), options_)) { + auto utf8_check = internal::cpp::GetUtf8CheckMode( + descriptor_->field(0), GetOptimizeFor(descriptor_->file(), options_) == + FileOptions::LITE_RUNTIME); + if (descriptor_->field(0)->type() == FieldDescriptor::TYPE_STRING && + utf8_check != Utf8CheckMode::kNone) { + if (utf8_check == Utf8CheckMode::kStrict) { format( - "bool PackFrom(const ::$proto_ns$::Message& message) {\n" - " $DCHK$_NE(&message, this);\n" - " return $any_metadata$.PackFrom(GetArena(), message);\n" - "}\n" - "bool PackFrom(const ::$proto_ns$::Message& message,\n" - " ::absl::string_view type_url_prefix) {\n" - " $DCHK$_NE(&message, this);\n" - " return $any_metadata$.PackFrom(GetArena(), message, " - "type_url_prefix);\n" - "}\n" - "bool UnpackTo(::$proto_ns$::Message* message) const {\n" - " return $any_metadata$.UnpackTo(message);\n" - "}\n" - "static bool GetAnyFieldDescriptors(\n" - " const ::$proto_ns$::Message& message,\n" - " const ::$proto_ns$::FieldDescriptor** type_url_field,\n" - " const ::$proto_ns$::FieldDescriptor** value_field);\n" - "template " - "::value>::type>\n" - "bool PackFrom(const T& message) {\n" - " return $any_metadata$.PackFrom(GetArena(), message);\n" - "}\n" - "template " - "::value>::type>\n" - "bool PackFrom(const T& message,\n" - " ::absl::string_view type_url_prefix) {\n" - " return $any_metadata$.PackFrom(GetArena(), message, " - "type_url_prefix);" - "}\n" - "template " - "::value>::type>\n" - "bool UnpackTo(T* message) const {\n" - " return $any_metadata$.UnpackTo(message);\n" - "}\n"); + " static bool ValidateKey(std::string* s) {\n" + " return ::$proto_ns$::internal::WireFormatLite::" + "VerifyUtf8String(s->data(), static_cast(s->size()), " + "::$proto_ns$::internal::WireFormatLite::PARSE, \"$1$\");\n" + " }\n", + descriptor_->field(0)->full_name()); } else { + ABSL_CHECK(utf8_check == Utf8CheckMode::kVerify); format( - "template \n" - "bool PackFrom(const T& message) {\n" - " return $any_metadata$.PackFrom(GetArena(), message);\n" - "}\n" - "template \n" - "bool PackFrom(const T& message,\n" - " ::absl::string_view type_url_prefix) {\n" - " return $any_metadata$.PackFrom(GetArena(), message, " - "type_url_prefix);\n" - "}\n" - "template \n" - "bool UnpackTo(T* message) const {\n" - " return $any_metadata$.UnpackTo(message);\n" - "}\n"); + " static bool ValidateKey(std::string* s) {\n" + "#ifndef NDEBUG\n" + " ::$proto_ns$::internal::WireFormatLite::VerifyUtf8String(\n" + " s->data(), static_cast(s->size()), " + "::$proto_ns$::internal::" + "WireFormatLite::PARSE, \"$1$\");\n" + "#else\n" + " (void) s;\n" + "#endif\n" + " return true;\n" + " }\n", + descriptor_->field(0)->full_name()); } - format( - "template bool Is() const {\n" - " return $any_metadata$.Is();\n" - "}\n" - "static bool ParseAnyTypeUrl(::absl::string_view type_url,\n" - " std::string* full_type_name);\n"); + } else { + format(" static bool ValidateKey(void*) { return true; }\n"); } - - format( - "friend void swap($classname$& a, $classname$& b) {\n" - " a.Swap(&b);\n" - "}\n" - "inline void Swap($classname$* other) {\n" - " if (other == this) return;\n" - "#ifdef PROTOBUF_FORCE_COPY_IN_SWAP\n" - " if (GetArena() != nullptr &&\n" - " GetArena() == other->GetArena()) {\n " - "#else // PROTOBUF_FORCE_COPY_IN_SWAP\n" - " if (GetArena() == other->GetArena()) {\n" - "#endif // !PROTOBUF_FORCE_COPY_IN_SWAP\n" - " InternalSwap(other);\n" - " } else {\n" - " $pbi$::GenericSwap(this, other);\n" - " }\n" - "}\n" - "void UnsafeArenaSwap($classname$* other) {\n" - " if (other == this) return;\n" - " $DCHK$(GetArena() == other->GetArena());\n" - " InternalSwap(other);\n" - "}\n"); - - format( - "\n" - "// implements Message ----------------------------------------------\n" - "\n" - "$classname$* New(::$proto_ns$::Arena* arena = nullptr) const final {\n" - " return CreateMaybeMessage<$classname$>(arena);\n" - "}\n"); - - // For instances that derive from Message (rather than MessageLite), some - // methods are virtual and should be marked as final. - auto v2 = p->WithVars( - {{"full_final", - HasDescriptorMethods(descriptor_->file(), options_) ? "final" : ""}}); - - if (HasGeneratedMethods(descriptor_->file(), options_)) { - if (HasDescriptorMethods(descriptor_->file(), options_)) { - if (!HasSimpleBaseClass(descriptor_, options_)) { - format( - // Use Message's built-in MergeFrom and CopyFrom when the passed-in - // argument is a generic Message instance, and only define the - // custom MergeFrom and CopyFrom instances when the source of the - // merge/copy is known to be the same class as the destination. - "using $superclass$::CopyFrom;\n" - "void CopyFrom(const $classname$& from);\n" - "" - "using $superclass$::MergeFrom;\n" - "void MergeFrom(" - " const $classname$& from) {\n" - " $classname$::MergeImpl(*this, from);\n" - "}\n" - "private:\n" - "static void MergeImpl(::$proto_ns$::Message& to_msg, const " - "::$proto_ns$::Message& from_msg);\n" - "public:\n"); - } else { - format( - "using $superclass$::CopyFrom;\n" - "inline void CopyFrom(const $classname$& from) {\n" - " $superclass$::CopyImpl(*this, from);\n" - "}\n" - "" - "using $superclass$::MergeFrom;\n" - "void MergeFrom(const $classname$& from) {\n" - " $superclass$::MergeImpl(*this, from);\n" - "}\n" - "public:\n"); - } - } else { + if (descriptor_->field(1)->type() == FieldDescriptor::TYPE_STRING && + utf8_check != Utf8CheckMode::kNone) { + if (utf8_check == Utf8CheckMode::kStrict) { format( - "void CheckTypeAndMergeFrom(const ::$proto_ns$::MessageLite& from)" - " final;\n" - "void CopyFrom(const $classname$& from);\n" - "void MergeFrom(const $classname$& from);\n"); - } - - if (!HasSimpleBaseClass(descriptor_, options_)) { - format( - "ABSL_ATTRIBUTE_REINITIALIZES void Clear() final;\n" - "bool IsInitialized() const final;\n" - "\n" - "::size_t ByteSizeLong() const final;\n"); - - parse_function_generator_->GenerateMethodDecls(p); - + " static bool ValidateValue(std::string* s) {\n" + " return ::$proto_ns$::internal::WireFormatLite::" + "VerifyUtf8String(s->data(), static_cast(s->size()), " + "::$proto_ns$::internal::WireFormatLite::PARSE, \"$1$\");\n" + " }\n", + descriptor_->field(1)->full_name()); + } else { + ABSL_CHECK(utf8_check == Utf8CheckMode::kVerify); format( - "$uint8$* _InternalSerialize(\n" - " $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) " - "const final;\n"); + " static bool ValidateValue(std::string* s) {\n" + "#ifndef NDEBUG\n" + " ::$proto_ns$::internal::WireFormatLite::VerifyUtf8String(\n" + " s->data(), static_cast(s->size()), " + "::$proto_ns$::internal::" + "WireFormatLite::PARSE, \"$1$\");\n" + "#else\n" + " (void) s;\n" + "#endif\n" + " return true;\n" + " }\n", + descriptor_->field(1)->full_name()); } + } else { + format(" static bool ValidateValue(void*) { return true; }\n"); } - - if (options_.field_listener_options.inject_field_listener_events) { - format("static constexpr int _kInternalFieldNumber = $1$;\n", - descriptor_->field_count()); - } - - if (!HasSimpleBaseClass(descriptor_, options_)) { - p->Emit( - R"cc( - int GetCachedSize() const { return $cached_size$.Get(); } - - private: - $pbi$::CachedSize* AccessCachedSize() const final; - void SharedCtor(::$proto_ns$::Arena* arena); - void SharedDtor(); - void InternalSwap($classname$* other); - )cc"); - } - - format( - // Friend AnyMetadata so that it can call this FullMessageName() method. - "\nprivate:\n" - "friend class ::$proto_ns$::internal::AnyMetadata;\n" - "static ::absl::string_view FullMessageName() {\n" - " return \"$full_name$\";\n" - "}\n"); - - format( - // TODO Make this private! Currently people are deriving from - // protos to give access to this constructor, breaking the invariants - // we rely on. - "protected:\n" - "explicit $classname$(::$proto_ns$::Arena* arena);\n" - "$classname$(::$proto_ns$::Arena* arena, const $classname$& from);\n" - ); - - switch (NeedsArenaDestructor()) { - case ArenaDtorNeeds::kOnDemand: - p->Emit(R"cc( - private: - static void ArenaDtor(void* object); - static void OnDemandRegisterArenaDtor(MessageLite& msg, - ::$proto_ns$::Arena& arena) { - auto& this_ = static_cast<$classname$&>(msg); - if ((this_.$inlined_string_donated_array$[0] & 0x1u) == 0) { - return; - } - this_.$inlined_string_donated_array$[0] &= 0xFFFFFFFEu; - arena.OwnCustomDestructor(&this_, &$classname$::ArenaDtor); - } - )cc"); - break; - case ArenaDtorNeeds::kRequired: - format( - "private:\n" - "static void ArenaDtor(void* object);\n"); - break; - case ArenaDtorNeeds::kNone: - break; - } - - if (!HasSimpleBaseClass(descriptor_, options_)) { - p->Emit(R"cc( - const ::$proto_ns$::MessageLite::ClassData* GetClassData() const final; - )cc"); - } - - format( - "public:\n" - "\n"); - if (HasDescriptorMethods(descriptor_->file(), options_)) { - format( - "::$proto_ns$::Metadata GetMetadata() const final;\n" - "\n"); - } - - if (ShouldSplit(descriptor_, options_)) { - format( - "private:\n" - "inline bool IsSplitMessageDefault() const {\n" - " return $split$ == reinterpret_cast(&$1$);\n" - "}\n" - "PROTOBUF_NOINLINE void PrepareSplitMessageForWrite();\n" - "public:\n", - DefaultInstanceName(descriptor_, options_, /*split=*/true)); + format(" ::$proto_ns$::Metadata GetMetadata() const final;\n"); } - format( - "// nested types ----------------------------------------------------\n" - "\n"); + " friend struct ::$tablename$;\n" + "};\n"); +} - // Import all nested message classes into this class's scope with typedefs. - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - const Descriptor* nested_type = descriptor_->nested_type(i); - if (!IsMapEntryMessage(nested_type)) { - p->Emit( - { - Sub{"nested_full_name", ClassName(nested_type, false)} - .AnnotatedAs(nested_type), - Sub{"nested_name", ResolveKeyword(nested_type->name())} - .AnnotatedAs(nested_type), - }, - R"cc( - using $nested_name$ = $nested_full_name$; - )cc"); - } - } +void MessageGenerator::GenerateImplDefinition(io::Printer* p) { + // Prepare decls for _cached_size_ and _has_bits_. Their position in the + // output will be determined later. + bool need_to_emit_cached_size = !HasSimpleBaseClass(descriptor_, options_); + const size_t sizeof_has_bits = HasBitsSize(); - if (descriptor_->nested_type_count() > 0) { - format("\n"); - } + // To minimize padding, data members are divided into three sections: + // (1) members assumed to align to 8 bytes + // (2) members corresponding to message fields, re-ordered to optimize + // alignment. + // (3) members assumed to align to 4 bytes. + p->Emit( + {{"extension_set", + [&] { + if (descriptor_->extension_range_count() == 0) return; - // Import all nested enums and their values into this class's scope with - // typedefs and constants. - for (int i = 0; i < descriptor_->enum_type_count(); i++) { - enum_generators_[i]->GenerateSymbolImports(p); - format("\n"); - } + p->Emit(R"cc( + ::$proto_ns$::internal::ExtensionSet _extensions_; + )cc"); + }}, + {"tracker", + [&] { + if (!HasTracker(descriptor_, options_)) return; - format( - "// accessors -------------------------------------------------------\n" - "\n"); + p->Emit(R"cc( + static ::$proto_ns$::AccessListener<$Msg$> _tracker_; + )cc"); + }}, + {"inlined_string_donated", + [&] { + // Generate _inlined_string_donated_ for inlined string type. + // TODO: To avoid affecting the locality of + // `_has_bits_`, should this be below or above `_has_bits_`? + if (inlined_string_indices_.empty()) return; + + p->Emit({{"donated_size", InlinedStringDonatedSize()}}, + R"cc( + ::$proto_ns$::internal::HasBits<$donated_size$> + _inlined_string_donated_; + )cc"); + }}, + {"has_bits", + [&] { + if (has_bit_indices_.empty()) return; + + // _has_bits_ is frequently accessed, so to reduce code size and + // improve speed, it should be close to the start of the object. + // Placing _cached_size_ together with _has_bits_ improves cache + // locality despite potential alignment padding. + p->Emit({{"sizeof_has_bits", sizeof_has_bits}}, R"cc( + ::$proto_ns$::internal::HasBits<$sizeof_has_bits$> _has_bits_; + )cc"); + if (need_to_emit_cached_size) { + p->Emit(R"cc( + mutable ::$proto_ns$::internal::CachedSize _cached_size_; + )cc"); + need_to_emit_cached_size = false; + } + }}, + {"field_members", + [&] { + // Emit some private and static members + for (auto field : optimized_order_) { + field_generators_.get(field).GenerateStaticMembers(p); + if (!ShouldSplit(field, options_)) { + field_generators_.get(field).GeneratePrivateMembers(p); + } + } + }}, + {"decl_split", + [&] { + if (!ShouldSplit(descriptor_, options_)) return; + p->Emit({{"split_field", + [&] { + for (auto field : optimized_order_) { + if (!ShouldSplit(field, options_)) continue; + field_generators_.get(field).GeneratePrivateMembers(p); + } + }}}, + R"cc( + struct Split { + $split_field$; + using InternalArenaConstructable_ = void; + using DestructorSkippable_ = void; + }; + static_assert(std::is_trivially_copy_constructible::value); + static_assert(std::is_trivially_destructible::value); + Split* _split_; + )cc"); + }}, + {"oneof_members", + [&] { + // For each oneof generate a union + for (auto oneof : OneOfRange(descriptor_)) { + // explicit empty constructor is needed when union contains + // ArenaStringPtr members for string fields. + p->Emit( + {{"camel_oneof_name", + UnderscoresToCamelCase(oneof->name(), true)}, + {"oneof_name", oneof->name()}, + {"oneof_fields", + [&] { + for (auto field : FieldRange(oneof)) { + field_generators_.get(field).GeneratePrivateMembers(p); + } + }}}, + R"cc( + union $camel_oneof_name$Union { + constexpr $camel_oneof_name$Union() : _constinit_{} {} + ::$proto_ns$::internal::ConstantInitialized _constinit_; + $oneof_fields$; + } $oneof_name$_; + )cc"); + for (auto field : FieldRange(oneof)) { + field_generators_.get(field).GenerateStaticMembers(p); + } + } + }}, + {"cached_size_if_no_hasbits", + [&] { + if (!need_to_emit_cached_size) return; - // Generate accessor methods for all fields. - GenerateFieldAccessorDeclarations(p); + need_to_emit_cached_size = false; + p->Emit(R"cc( + mutable ::$proto_ns$::internal::CachedSize _cached_size_; + )cc"); + }}, + {"oneof_case", + [&] { + // Generate _oneof_case_. + if (descriptor_->real_oneof_decl_count() == 0) return; - // Declare extension identifiers. - for (int i = 0; i < descriptor_->extension_count(); i++) { - extension_generators_[i]->GenerateDeclaration(p); - } + p->Emit({{"count", descriptor_->real_oneof_decl_count()}}, + R"cc( + $uint32$ _oneof_case_[$count$]; + )cc"); + }}, + {"weak_field_map", + [&] { + if (num_weak_fields_ == 0) return; + p->Emit(R"cc( + ::$proto_ns$::internal::WeakFieldMap _weak_field_map_; + )cc"); + }}, + {"any_metadata", + [&] { + // Generate _any_metadata_ for the Any type. + if (!IsAnyMessage(descriptor_)) return; - format("// @@protoc_insertion_point(class_scope:$full_name$)\n"); + p->Emit(R"cc( + ::$proto_ns$::internal::AnyMetadata _any_metadata_; + )cc"); + }}, + {"union_impl", + [&] { + // Only create the _impl_ field if it contains data. + if (!HasImplData(descriptor_, options_)) return; - // Generate private members. - format.Outdent(); - format(" private:\n"); - format.Indent(); - // TODO: Remove hack to track field access and remove this class. - format("class _Internal;\n"); + // clang-format off + p->Emit(R"cc(union { Impl_ _impl_; };)cc"); + // clang-format on + }}}, + R"cc( + struct Impl_ { + //~ TODO: check if/when there is a need for an + //~ outline dtor. + inline explicit constexpr Impl_( + ::$proto_ns$::internal::ConstantInitialized) noexcept; + inline explicit Impl_($pbi$::InternalVisibility visibility, + ::$proto_ns$::Arena* arena); + inline explicit Impl_($pbi$::InternalVisibility visibility, + ::$proto_ns$::Arena* arena, const Impl_& from); + //~ Members assumed to align to 8 bytes: + $extension_set$; + $tracker$; + $inlined_string_donated$; + $has_bits$; + //~ Field members: + $field_members$; + $decl_split$; + $oneof_members$; + //~ Members assumed to align to 4 bytes: + $cached_size_if_no_hasbits$; + $oneof_case$; + $weak_field_map$; + $any_metadata$; + //~ For detecting when concurrent accessor calls cause races. + PROTOBUF_TSAN_DECLARE_MEMBER + }; + $union_impl$; + )cc"); - for (auto field : FieldRange(descriptor_)) { - // set_has_***() generated in all oneofs. - if (!field->is_repeated() && !field->options().weak() && - field->real_containing_oneof()) { - format("void set_has_$1$();\n", FieldName(field)); - } - } - format("\n"); + ABSL_DCHECK(!need_to_emit_cached_size); +} - // Generate oneof function declarations - for (auto oneof : OneOfRange(descriptor_)) { - format( - "inline bool has_$1$() const;\n" - "inline void clear_has_$1$();\n\n", - oneof->name()); - } +void MessageGenerator::GenerateAnyMethodDefinition(io::Printer* p) { + ABSL_DCHECK(IsAnyMessage(descriptor_)); - if (HasGeneratedMethods(descriptor_->file(), options_)) { - parse_function_generator_->GenerateDataDecls(p); - } + p->Emit({{"any_methods", + [&] { + if (HasDescriptorMethods(descriptor_->file(), options_)) { + p->Emit( + R"cc( + bool PackFrom(const ::$proto_ns$::Message& message) { + $DCHK$_NE(&message, this); + return $any_metadata$.PackFrom(GetArena(), message); + } + bool PackFrom(const ::$proto_ns$::Message& message, + ::absl::string_view type_url_prefix) { + $DCHK$_NE(&message, this); + return $any_metadata$.PackFrom(GetArena(), message, type_url_prefix); + } + bool UnpackTo(::$proto_ns$::Message* message) const { + return $any_metadata$.UnpackTo(message); + } + static bool GetAnyFieldDescriptors( + const ::$proto_ns$::Message& message, + const ::$proto_ns$::FieldDescriptor** type_url_field, + const ::$proto_ns$::FieldDescriptor** value_field); + template < + typename T, + class = typename std::enable_if::value>::type> + bool PackFrom(const T& message) { + return $any_metadata$.PackFrom(GetArena(), message); + } + template < + typename T, + class = typename std::enable_if::value>::type> + bool PackFrom(const T& message, + ::absl::string_view type_url_prefix) { + return $any_metadata$.PackFrom(GetArena(), message, type_url_prefix); + } + template < + typename T, + class = typename std::enable_if::value>::type> + bool UnpackTo(T* message) const { + return $any_metadata$.UnpackTo(message); + } + )cc"); + } else { + p->Emit( + R"cc( + template + bool PackFrom(const T& message) { + return $any_metadata$.PackFrom(GetArena(), message); + } + template + bool PackFrom(const T& message, + ::absl::string_view type_url_prefix) { + return $any_metadata$.PackFrom(GetArena(), message, type_url_prefix); + } + template + bool UnpackTo(T* message) const { + return $any_metadata$.UnpackTo(message); + } + )cc"); + } + }}}, + R"cc( + // implements Any + // ----------------------------------------------- - // Prepare decls for _cached_size_ and _has_bits_. Their position in the - // output will be determined later. + $any_methods$; - bool need_to_emit_cached_size = !HasSimpleBaseClass(descriptor_, options_); - const std::string cached_size_decl = - "mutable ::$proto_ns$::internal::CachedSize _cached_size_;\n"; + template + bool Is() const { + return $any_metadata$.Is(); + } + static bool ParseAnyTypeUrl(::absl::string_view type_url, + std::string* full_type_name); + )cc"); +} - const size_t sizeof_has_bits = HasBitsSize(); - const std::string has_bits_decl = - sizeof_has_bits == 0 ? "" - : absl::StrCat("::$proto_ns$::internal::HasBits<", - sizeof_has_bits, "> _has_bits_;\n"); +void MessageGenerator::GenerateClassDefinition(io::Printer* p) { + if (!ShouldGenerateClass(descriptor_, options_)) return; - p->Emit(R"cc( - friend class ::$proto_ns$::MessageLite; - friend class ::$proto_ns$::Arena; - template - friend class ::$proto_ns$::Arena::InternalHelper; - using InternalArenaConstructable_ = void; - using DestructorSkippable_ = void; - )cc"); + auto v = p->WithVars(ClassVars(descriptor_, options_)); + auto t = p->WithVars(MakeTrackerCalls(descriptor_, options_)); + Formatter format(p); - // To minimize padding, data members are divided into three sections: - // (1) members assumed to align to 8 bytes - // (2) members corresponding to message fields, re-ordered to optimize - // alignment. - // (3) members assumed to align to 4 bytes. + if (IsMapEntryMessage(descriptor_)) { + GenerateMapEntryClassDefinition(p); + return; + } - format("struct $dllexport_decl $Impl_ {\n"); - format.Indent(); + auto annotation = p->WithAnnotations({{"classname", descriptor_}}); + p->Emit( + {{"decl_dtor", + [&] { + if (HasSimpleBaseClass(descriptor_, options_)) return; - // TODO: check if/when there is a need for an outline dtor. - format(R"cc( - inline explicit constexpr Impl_( - ::$proto_ns$::internal::ConstantInitialized) noexcept; - inline explicit Impl_($pbi$::InternalVisibility visibility, - ::$proto_ns$::Arena* arena); - inline explicit Impl_($pbi$::InternalVisibility visibility, - ::$proto_ns$::Arena* arena, const Impl_& from); - )cc"); + p->Emit(R"cc( + ~$classname$() override; + )cc"); + }}, + {"decl_annotate", + [&] { + }}, + {"decl_verify_func", + [&] { + }}, + {"descriptor_accessor", + [&] { + // Only generate this member if it's not disabled. + if (!HasDescriptorMethods(descriptor_->file(), options_) || + descriptor_->options().no_standard_descriptor_accessor()) { + return; + } - // Members assumed to align to 8 bytes: + p->Emit(R"cc( + static const ::$proto_ns$::Descriptor* descriptor() { + return GetDescriptor(); + } + )cc"); + }}, + {"get_descriptor", + [&] { + // These shadow non-static methods of the same names in Message. + // We redefine them here because calls directly on the generated + // class can be statically analyzed -- we know what descriptor + // types are being requested. It also avoids a vtable dispatch. + // + // We would eventually like to eliminate the methods in Message, + // and having this separate also lets us track calls to the base + // class methods separately. + if (!HasDescriptorMethods(descriptor_->file(), options_)) return; + + p->Emit(R"cc( + static const ::$proto_ns$::Descriptor* GetDescriptor() { + return default_instance().GetMetadata().descriptor; + } + static const ::$proto_ns$::Reflection* GetReflection() { + return default_instance().GetMetadata().reflection; + } + )cc"); + }}, + {"decl_oneof", + [&] { + // Generate enum values for every field in oneofs. One list is + // generated for each oneof with an additional *_NOT_SET value. + for (auto oneof : OneOfRange(descriptor_)) { + p->Emit( + {{"oneof_camel_name", + UnderscoresToCamelCase(oneof->name(), true)}, + {"oneof_field", + [&] { + for (auto field : FieldRange(oneof)) { + p->Emit( + { + {"oneof_constant", OneofCaseConstantName(field)}, + {"field_number", field->number()}, + }, + R"cc( + $oneof_constant$ = $field_number$, + )cc"); + } + }}, + {"upper_oneof_name", absl::AsciiStrToUpper(oneof->name())}}, + R"cc( + enum $oneof_camel_name$Case { + $oneof_field$, + $upper_oneof_name$_NOT_SET = 0, + }; + )cc"); + } + }}, + {"index_in_file_messages", index_in_file_messages_}, + {"decl_any_methods", + [&] { + if (!IsAnyMessage(descriptor_)) return; - if (descriptor_->extension_range_count() > 0) { - format( - "::$proto_ns$::internal::ExtensionSet _extensions_;\n" - "\n"); - } + GenerateAnyMethodDefinition(p); + }}, + {"generated_methods", + [&] { + if (!HasGeneratedMethods(descriptor_->file(), options_)) return; + + if (HasDescriptorMethods(descriptor_->file(), options_)) { + if (!HasSimpleBaseClass(descriptor_, options_)) { + // Use Message's built-in MergeFrom and CopyFrom when the + // passed-in argument is a generic Message instance, and + // only define the custom MergeFrom and CopyFrom + // instances when the source of the merge/copy is known + // to be the same class as the destination. + p->Emit(R"cc( + using $superclass$::CopyFrom; + void CopyFrom(const $classname$& from); + using $superclass$::MergeFrom; + void MergeFrom(const $classname$& from) { $classname$::MergeImpl(*this, from); } - if (HasTracker(descriptor_, options_)) { - format("static ::$proto_ns$::AccessListener<$1$> _tracker_;\n", - ClassName(descriptor_)); - } + private: + static void MergeImpl( + ::$proto_ns$::MessageLite& to_msg, + const ::$proto_ns$::MessageLite& from_msg); - // Generate _inlined_string_donated_ for inlined string type. - // TODO: To avoid affecting the locality of `_has_bits_`, should this - // be below or above `_has_bits_`? - if (!inlined_string_indices_.empty()) { - format("::$proto_ns$::internal::HasBits<$1$> _inlined_string_donated_;\n", - InlinedStringDonatedSize()); - } + public: + )cc"); + } else { + p->Emit(R"cc( + using $superclass$::CopyFrom; + inline void CopyFrom(const $classname$& from) { + $superclass$::CopyImpl(*this, from); + } + using $superclass$::MergeFrom; + void MergeFrom(const $classname$& from) { + $superclass$::MergeImpl(*this, from); + } - if (!has_bit_indices_.empty()) { - // _has_bits_ is frequently accessed, so to reduce code size and improve - // speed, it should be close to the start of the object. Placing - // _cached_size_ together with _has_bits_ improves cache locality despite - // potential alignment padding. - format(has_bits_decl.c_str()); - if (need_to_emit_cached_size) { - format(cached_size_decl.c_str()); - need_to_emit_cached_size = false; - } - } + public: + )cc"); + } + } else { + p->Emit(R"cc( + void CheckTypeAndMergeFrom( + const ::$proto_ns$::MessageLite& from) final; + void CopyFrom(const $classname$& from); + void MergeFrom(const $classname$& from); + )cc"); + } - // Field members: + if (!HasSimpleBaseClass(descriptor_, options_)) { + p->Emit(R"cc( + ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; + bool IsInitialized() const final; - // Emit some private and static members - for (auto field : optimized_order_) { - field_generators_.get(field).GenerateStaticMembers(p); - if (!ShouldSplit(field, options_)) { - field_generators_.get(field).GeneratePrivateMembers(p); - } - } - if (ShouldSplit(descriptor_, options_)) { - format("struct Split {\n"); - format.Indent(); - for (auto field : optimized_order_) { - if (!ShouldSplit(field, options_)) continue; - field_generators_.get(field).GeneratePrivateMembers(p); - } - format.Outdent(); - p->Emit(R"cc( - using InternalArenaConstructable_ = void; - using DestructorSkippable_ = void; - )cc"); - format( - "};\n" - "static_assert(std::is_trivially_copy_constructible::value);\n" - "static_assert(std::is_trivially_destructible::value);\n" - "Split* _split_;\n"); - } + ::size_t ByteSizeLong() const final; + )cc"); - // For each oneof generate a union - for (auto oneof : OneOfRange(descriptor_)) { - std::string camel_oneof_name = UnderscoresToCamelCase(oneof->name(), true); - format("union $1$Union {\n", camel_oneof_name); - format.Indent(); - format( - // explicit empty constructor is needed when union contains - // ArenaStringPtr members for string fields. - "constexpr $1$Union() : _constinit_{} {}\n" - " ::$proto_ns$::internal::ConstantInitialized _constinit_;\n", - camel_oneof_name); - for (auto field : FieldRange(oneof)) { - field_generators_.get(field).GeneratePrivateMembers(p); - } - format.Outdent(); - format("} $1$_;\n", oneof->name()); - for (auto field : FieldRange(oneof)) { - field_generators_.get(field).GenerateStaticMembers(p); - } - } + parse_function_generator_->GenerateMethodDecls(p); - // Members assumed to align to 4 bytes: + p->Emit(R"cc( + $uint8$* _InternalSerialize( + $uint8$* target, + ::$proto_ns$::io::EpsCopyOutputStream* stream) const final; + )cc"); + } + }}, + {"internal_field_number", + [&] { + if (!options_.field_listener_options.inject_field_listener_events) + return; - if (need_to_emit_cached_size) { - format(cached_size_decl.c_str()); - need_to_emit_cached_size = false; - } + p->Emit({{"field_count", descriptor_->field_count()}}, R"cc( + static constexpr int _kInternalFieldNumber = $field_count$; + )cc"); + }}, + {"decl_non_simple_base", + [&] { + if (HasSimpleBaseClass(descriptor_, options_)) return; + p->Emit( + R"cc( + int GetCachedSize() const { return $cached_size$.Get(); } - // Generate _oneof_case_. - if (descriptor_->real_oneof_decl_count() > 0) { - format( - "$uint32$ _oneof_case_[$1$];\n" - "\n", - descriptor_->real_oneof_decl_count()); - } + private: + void SharedCtor(::$proto_ns$::Arena* arena); + void SharedDtor(); + void InternalSwap($classname$* other); + )cc"); + }}, + {"arena_dtor", + [&] { + switch (NeedsArenaDestructor()) { + case ArenaDtorNeeds::kOnDemand: + p->Emit(R"cc( + private: + static void ArenaDtor(void* object); + static void OnDemandRegisterArenaDtor( + MessageLite& msg, ::$proto_ns$::Arena& arena) { + auto& this_ = static_cast<$classname$&>(msg); + if ((this_.$inlined_string_donated_array$[0] & 0x1u) == 0) { + return; + } + this_.$inlined_string_donated_array$[0] &= 0xFFFFFFFEu; + arena.OwnCustomDestructor(&this_, &$classname$::ArenaDtor); + } + )cc"); + break; + case ArenaDtorNeeds::kRequired: + p->Emit(R"cc( + private: + static void ArenaDtor(void* object); + )cc"); + break; + case ArenaDtorNeeds::kNone: + break; + } + }}, + {"get_class_data", + [&] { + if (HasSimpleBaseClass(descriptor_, options_)) return; - if (num_weak_fields_) { - format("::$proto_ns$::internal::WeakFieldMap _weak_field_map_;\n"); - } - // Generate _any_metadata_ for the Any type. - if (IsAnyMessage(descriptor_)) { - format("::$proto_ns$::internal::AnyMetadata _any_metadata_;\n"); - } + p->Emit(R"cc( + const ::$proto_ns$::MessageLite::ClassData* GetClassData() + const final; + )cc"); + }}, + {"get_metadata", + [&] { + if (!HasDescriptorMethods(descriptor_->file(), options_)) return; - // For detecting when concurrent accessor calls cause races. - format("PROTOBUF_TSAN_DECLARE_MEMBER\n"); + p->Emit(R"cc( + ::$proto_ns$::Metadata GetMetadata() const final; + )cc"); + }}, + {"decl_split_methods", + [&] { + if (!ShouldSplit(descriptor_, options_)) return; + p->Emit({{"default_name", DefaultInstanceName(descriptor_, options_, + /*split=*/true)}}, + R"cc( + private: + inline bool IsSplitMessageDefault() const { + return $split$ == reinterpret_cast(&$default_name$); + } + PROTOBUF_NOINLINE void PrepareSplitMessageForWrite(); + + public: + )cc"); + }}, + {"nested_types", + [&] { + // Import all nested message classes into this class's scope with + // typedefs. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + const Descriptor* nested_type = descriptor_->nested_type(i); + if (!IsMapEntryMessage(nested_type)) { + p->Emit( + { + Sub{"nested_full_name", ClassName(nested_type, false)} + .AnnotatedAs(nested_type), + Sub{"nested_name", ResolveKeyword(nested_type->name())} + .AnnotatedAs(nested_type), + }, + R"cc( + using $nested_name$ = $nested_full_name$; + )cc"); + } + } + }}, + {"nested_enums", + [&] { + // Import all nested enums and their values into this class's + // scope with typedefs and constants. + for (int i = 0; i < descriptor_->enum_type_count(); i++) { + enum_generators_[i]->GenerateSymbolImports(p); + } + }}, + {"decl_field_accessors", + [&] { + // Generate accessor methods for all fields. + GenerateFieldAccessorDeclarations(p); + }}, + {"decl_extension_ids", + [&] { + // Declare extension identifiers. + for (int i = 0; i < descriptor_->extension_count(); i++) { + extension_generators_[i]->GenerateDeclaration(p); + } + }}, + {"proto2_message_sets", + [&] { + }}, + {"decl_set_has", + [&] { + for (auto field : FieldRange(descriptor_)) { + // set_has_***() generated in all oneofs. + if (!field->is_repeated() && !field->options().weak() && + field->real_containing_oneof()) { + p->Emit({{"field_name", FieldName(field)}}, R"cc( + void set_has_$field_name$(); + )cc"); + } + } + }}, + {"decl_oneof_has", + [&] { + // Generate oneof function declarations + for (auto oneof : OneOfRange(descriptor_)) { + p->Emit({{"oneof_name", oneof->name()}}, R"cc( + inline bool has_$oneof_name$() const; + inline void clear_has_$oneof_name$(); + )cc"); + } + }}, + {"decl_data", + [&] { + if (HasGeneratedMethods(descriptor_->file(), options_)) { + parse_function_generator_->GenerateDataDecls(p); + } + }}, + {"decl_impl", [&] { GenerateImplDefinition(p); }}, + {"split_friend", + [&] { + if (!ShouldSplit(descriptor_, options_)) return; - format.Outdent(); - format("};\n"); + p->Emit({{"split_default", DefaultInstanceType(descriptor_, options_, + /*split=*/true)}}, + R"cc( + friend struct $split_default$; + )cc"); + }}}, + R"cc( + class $dllexport_decl $$classname$ final : public $superclass$ + /* @@protoc_insertion_point(class_definition:$full_name$) */ { + public: + inline $classname$() : $classname$(nullptr) {} + $decl_dtor$; + //~ Templatize constexpr constructor as a workaround for a bug in + //~ gcc 12 (warning in gcc 13). + template + explicit PROTOBUF_CONSTEXPR $classname$( + ::$proto_ns$::internal::ConstantInitialized); + + inline $classname$(const $classname$& from) : $classname$(nullptr, from) {} + inline $classname$($classname$&& from) noexcept + : $classname$(nullptr, std::move(from)) {} + inline $classname$& operator=(const $classname$& from) { + CopyFrom(from); + return *this; + } + inline $classname$& operator=($classname$&& from) noexcept { + if (this == &from) return *this; + if (GetArena() == from.GetArena() +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE + && GetArena() != nullptr +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE + ) { + InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + $decl_annotate$; + $decl_verify_func$; - // Only create the _impl_ field if it contains data. - if (HasImplData(descriptor_, options_)) { - format("union { Impl_ _impl_; };\n"); - } + inline const $unknown_fields_type$& unknown_fields() const + ABSL_ATTRIBUTE_LIFETIME_BOUND { + $annotate_unknown_fields$; + return $unknown_fields$; + } + inline $unknown_fields_type$* mutable_unknown_fields() + ABSL_ATTRIBUTE_LIFETIME_BOUND { + $annotate_mutable_unknown_fields$; + return $mutable_unknown_fields$; + } - if (ShouldSplit(descriptor_, options_)) { - format("friend struct $1$;\n", - DefaultInstanceType(descriptor_, options_, /*split=*/true)); - } + $descriptor_accessor$; + $get_descriptor$; + static const $classname$& default_instance() { + return *internal_default_instance(); + } + $decl_oneof$; + //~ TODO make this private, while still granting other + //~ protos access. + static inline const $classname$* internal_default_instance() { + return reinterpret_cast( + &_$classname$_default_instance_); + } + static constexpr int kIndexInFileMessages = $index_in_file_messages$; + $decl_any_methods$; + friend void swap($classname$& a, $classname$& b) { a.Swap(&b); } + inline void Swap($classname$* other) { + if (other == this) return; +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() == other->GetArena()) { +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP + InternalSwap(other); + } else { + $pbi$::GenericSwap(this, other); + } + } + void UnsafeArenaSwap($classname$* other) { + if (other == this) return; + $DCHK$(GetArena() == other->GetArena()); + InternalSwap(other); + } - // The TableStruct struct needs access to the private parts, in order to - // construct the offsets of all members. - format("friend struct ::$tablename$;\n"); + // implements Message ---------------------------------------------- - format.Outdent(); - format("};"); - ABSL_DCHECK(!need_to_emit_cached_size); + $classname$* New(::$proto_ns$::Arena* arena = nullptr) const final { + return $superclass$::DefaultConstruct<$classname$>(arena); + } + $generated_methods$; + $internal_field_number$; + $decl_non_simple_base$; + //~ Friend AnyMetadata so that it can call this FullMessageName() + //~ method. + private: + friend class ::$proto_ns$::internal::AnyMetadata; + static ::absl::string_view FullMessageName() { return "$full_name$"; } + + //~ TODO Make this private! Currently people are + //~ deriving from protos to give access to this constructor, + //~ breaking the invariants we rely on. + protected: + explicit $classname$(::$proto_ns$::Arena* arena); + $classname$(::$proto_ns$::Arena* arena, const $classname$& from); + $classname$(::$proto_ns$::Arena* arena, $classname$&& from) noexcept + : $classname$(arena) { + *this = ::std::move(from); + } + $arena_dtor$; + $get_class_data$; + + public: + $get_metadata$; + $decl_split_methods$; + // nested types ---------------------------------------------------- + $nested_types$; + $nested_enums$; + + // accessors ------------------------------------------------------- + $decl_field_accessors$; + $decl_extension_ids$; + $proto2_message_sets$; + // @@protoc_insertion_point(class_scope:$full_name$) + //~ Generate private members. + private: + //~ TODO: Remove hack to track field access and remove + //~ this class. + class _Internal; + $decl_set_has$; + $decl_oneof_has$; + $decl_data$; + friend class ::$proto_ns$::MessageLite; + friend class ::$proto_ns$::Arena; + template + friend class ::$proto_ns$::Arena::InternalHelper; + using InternalArenaConstructable_ = void; + using DestructorSkippable_ = void; + $decl_impl$; + $split_friend$; + //~ The TableStruct struct needs access to the private parts, in + //~ order to construct the offsets of all members. + friend struct ::$tablename$; + }; + )cc"); } // NOLINT(readability/fn_size) void MessageGenerator::GenerateInlineMethods(io::Printer* p) { @@ -1932,30 +2056,50 @@ void MessageGenerator::GenerateClassMethods(io::Printer* p) { auto v = p->WithVars(ClassVars(descriptor_, options_)); auto t = p->WithVars(MakeTrackerCalls(descriptor_, options_)); Formatter format(p); + + const auto pin_weak_writer = [&] { + if (!UsingImplicitWeakDescriptor(descriptor_->file(), options_)) return; + p->Emit({{"index", index_in_file_messages_}}, + R"cc( + ::_pbi::StrongPointer(&pb_$index$_weak_); + )cc"); + + // For CODE_SIZE types, we need to pin the submessages too. + // SPEED types will pin them via the TcParse table automatically. + if (HasGeneratedMethods(descriptor_->file(), options_)) return; + for (int i = 0; i < descriptor_->field_count(); ++i) { + auto* field = descriptor_->field(i); + if (field->type() != field->TYPE_MESSAGE) continue; + p->Emit( + { + {"sub_default_name", + QualifiedDefaultInstanceName(field->message_type(), options_)}, + }, + R"cc( + ::_pbi::StrongPointer(&$sub_default_name$); + )cc"); + } + }; + if (IsMapEntryMessage(descriptor_)) { format( "$classname$::$classname$() {}\n" "$classname$::$classname$(::$proto_ns$::Arena* arena)\n" " : SuperType(arena) {}\n"); if (HasDescriptorMethods(descriptor_->file(), options_)) { - if (!descriptor_->options().map_entry()) { - format( - "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" - "$annotate_reflection$" - " return ::_pbi::AssignDescriptors(\n" - " &$desc_table$_getter, &$desc_table$_once,\n" - " $file_level_metadata$[$1$]);\n" - "}\n", - index_in_file_messages_); - } else { - format( - "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" - " return ::_pbi::AssignDescriptors(\n" - " &$desc_table$_getter, &$desc_table$_once,\n" - " $file_level_metadata$[$1$]);\n" - "}\n", - index_in_file_messages_); - } + p->Emit( + { + {"pin_weak_writer", pin_weak_writer}, + {"index", index_in_file_messages_}, + }, + R"cc( + ::$proto_ns$::Metadata $classname$::GetMetadata() const { + $pin_weak_writer$; + return ::_pbi::AssignDescriptors(&$desc_table$_getter, + &$desc_table$_once, + $file_level_metadata$[$index$]); + } + )cc"); } return; } @@ -1996,19 +2140,6 @@ void MessageGenerator::GenerateClassMethods(io::Printer* p) { "static constexpr ::int32_t kOneofCaseOffset =\n" " PROTOBUF_FIELD_OFFSET($classtype$, $oneof_case$);\n"); } - for (auto field : FieldRange(descriptor_)) { - auto t = p->WithVars(MakeTrackerCalls(field, options_)); - field_generators_.get(field).GenerateInternalAccessorDeclarations(p); - if (HasHasbit(field)) { - int has_bit_index = HasBitIndex(field); - ABSL_CHECK_NE(has_bit_index, kNoHasbit) << field->full_name(); - format( - "static void set_has_$1$(HasBits* has_bits) {\n" - " (*has_bits)[$2$] |= $3$u;\n" - "}\n", - FieldName(field), has_bit_index / 32, (1u << (has_bit_index % 32))); - } - } if (num_required_fields_ > 0) { const std::vector masks_for_has_bits = RequiredFieldsBitMask(); format( @@ -2021,9 +2152,6 @@ void MessageGenerator::GenerateClassMethods(io::Printer* p) { format.Outdent(); format("};\n\n"); - for (auto field : FieldRange(descriptor_)) { - field_generators_.get(field).GenerateInternalAccessorDefinitions(p); - } // Generate non-inline field definitions. for (auto field : FieldRange(descriptor_)) { @@ -2088,38 +2216,26 @@ void MessageGenerator::GenerateClassMethods(io::Printer* p) { DefaultInstanceName(descriptor_, options_, /*split=*/false)); } - if (!HasSimpleBaseClass(descriptor_, options_)) { - p->Emit(R"cc( - ::_pbi::CachedSize* $classname$::AccessCachedSize() const { - return &$cached_size$; - } - )cc"); - } - GenerateVerify(p); GenerateSwap(p); format("\n"); if (HasDescriptorMethods(descriptor_->file(), options_)) { - if (!descriptor_->options().map_entry()) { - format( - "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" - "$annotate_reflection$" - " return ::_pbi::AssignDescriptors(\n" - " &$desc_table$_getter, &$desc_table$_once,\n" - " $file_level_metadata$[$1$]);\n" - "}\n", - index_in_file_messages_); - } else { - format( - "::$proto_ns$::Metadata $classname$::GetMetadata() const {\n" - " return ::_pbi::AssignDescriptors(\n" - " &$desc_table$_getter, &$desc_table$_once,\n" - " $file_level_metadata$[$1$]);\n" - "}\n", - index_in_file_messages_); - } + p->Emit( + { + {"pin_weak_writer", pin_weak_writer}, + {"index", index_in_file_messages_}, + }, + R"cc( + ::$proto_ns$::Metadata $classname$::GetMetadata() const { + $annotate_reflection$; + $pin_weak_writer$; + return ::_pbi::AssignDescriptors(&$desc_table$_getter, + &$desc_table$_once, + $file_level_metadata$[$index$]); + } + )cc"); } if (HasTracker(descriptor_, options_)) { @@ -2245,7 +2361,6 @@ std::pair MessageGenerator::GenerateOffsets(io::Printer* p) { return std::make_pair(entries, offsets); } - void MessageGenerator::GenerateZeroInitFields(io::Printer* p) const { using Iterator = decltype(optimized_order_.begin()); const FieldDescriptor* first = nullptr; @@ -2748,9 +2863,9 @@ void MessageGenerator::GenerateCopyInitFields(io::Printer* p) const { p->Emit({{"has_msg", [&] { has_message(field); }}, {"submsg", FieldMessageTypeName(field, options_)}}, R"cc( - $field$ = ($has_msg$) - ? CreateMaybeMessage<$submsg$>(arena, *from.$field$) - : nullptr; + $field$ = ($has_msg$) ? $superclass$::CopyConstruct<$submsg$>( + arena, *from.$field$) + : nullptr; )cc"); }; @@ -3009,26 +3124,12 @@ void MessageGenerator::GenerateSourceInProto2Namespace(io::Printer* p) { Formatter format(p); if (ShouldGenerateExternSpecializations(options_) && ShouldGenerateClass(descriptor_, options_)) { - format(R"cc( - template <> - PROTOBUF_NOINLINE $classtype$* Arena::CreateMaybeMessage<$classtype$>( - Arena* arena) { - using T = $classtype$; - void* mem = arena != nullptr ? arena->AllocateAligned(sizeof(T)) - : ::operator new(sizeof(T)); - return new (mem) T(arena); - } + p->Emit(R"cc( + template void* Arena::DefaultConstruct<$classtype$>(Arena*); )cc"); if (!IsMapEntryMessage(descriptor_)) { - format(R"cc( - template <> - PROTOBUF_NOINLINE $classtype$* Arena::CreateMaybeMessage<$classtype$>( - Arena* arena, const $classtype$& from) { - using T = $classtype$; - void* mem = arena != nullptr ? arena->AllocateAligned(sizeof(T)) - : ::operator new(sizeof(T)); - return new (mem) T(arena, from); - } + p->Emit(R"cc( + template void* Arena::CopyConstruct<$classtype$>(Arena*, const void*); )cc"); } } @@ -3440,6 +3541,7 @@ void MessageGenerator::GenerateClassData(io::Printer* p) { }, R"cc( $merge_impl$, $on_demand_register_arena_dtor$, $descriptor_methods$, + PROTOBUF_FIELD_OFFSET($classname$, $cached_size$), )cc"); }; @@ -3450,10 +3552,10 @@ void MessageGenerator::GenerateClassData(io::Printer* p) { const ::$proto_ns$::MessageLite::ClassData* $classname$::GetClassData() const { PROTOBUF_CONSTINIT static const ::$proto_ns$::MessageLite::ClassData - data = { + _data_ = { $class_data_members$, }; - return &data; + return &_data_; } )cc"); } else { @@ -3469,14 +3571,14 @@ void MessageGenerator::GenerateClassData(io::Printer* p) { ::$proto_ns$::MessageLite::ClassData header; char type_name[$type_size$]; }; - PROTOBUF_CONSTINIT static const ClassData_ data = { + PROTOBUF_CONSTINIT static const ClassData_ _data_ = { { $class_data_members$, }, "$full_name$", }; - return &data.header; + return &_data_.header; } )cc"); } @@ -3496,6 +3598,15 @@ void MessageGenerator::GenerateMergeFrom(io::Printer* p) { } } +bool MessageGenerator::RequiresArena(GeneratorFunction function) const { + for (const FieldDescriptor* field : FieldRange(descriptor_)) { + if (field_generators_.get(field).RequiresArena(function)) { + return true; + } + } + return false; +} + void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* p) { if (HasSimpleBaseClass(descriptor_, options_)) return; // Generate the class-specific MergeFrom, which avoids the ABSL_CHECK and @@ -3509,12 +3620,17 @@ void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* p) { " $classname$* const _this = this;\n"); } else { format( - "void $classname$::MergeImpl(::$proto_ns$::Message& to_msg, const " - "::$proto_ns$::Message& from_msg) {\n" + "void $classname$::MergeImpl(::$proto_ns$::MessageLite& to_msg, const " + "::$proto_ns$::MessageLite& from_msg) {\n" " auto* const _this = static_cast<$classname$*>(&to_msg);\n" " auto& from = static_cast(from_msg);\n"); } format.Indent(); + if (RequiresArena(GeneratorFunction::kMergeFrom)) { + p->Emit(R"cc( + ::$proto_ns$::Arena* arena = _this->GetArena(); + )cc"); + } format( "$annotate_mergefrom$" "// @@protoc_insertion_point(class_specific_merge_from_start:" @@ -3554,10 +3670,17 @@ void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* p) { while (it != next) { const std::vector& fields = it->fields; - const bool check_has_byte = fields.size() > 1 && - HasByteIndex(fields.front()) != kNoHasbit && + const bool cache_has_bits = HasByteIndex(fields.front()) != kNoHasbit; + const bool check_has_byte = cache_has_bits && fields.size() > 1 && !IsLikelyPresent(fields.back(), options_); + if (cache_has_bits && + cached_has_word_index != HasWordIndex(fields.front())) { + cached_has_word_index = HasWordIndex(fields.front()); + format("cached_has_bits = from.$has_bits$[$1$];\n", + cached_has_word_index); + } + if (check_has_byte) { // Emit an if() that will let us skip the whole chunk if none are set. uint32_t chunk_mask = GenChunkMask(fields, has_bit_indices_); @@ -3570,18 +3693,11 @@ void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* p) { ABSL_DCHECK_LE(2, popcnt(chunk_mask)); ABSL_DCHECK_GE(8, popcnt(chunk_mask)); - if (cached_has_word_index != HasWordIndex(fields.front())) { - cached_has_word_index = HasWordIndex(fields.front()); - format("cached_has_bits = from.$has_bits$[$1$];\n", - cached_has_word_index); - } - format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str); format.Indent(); } // Go back and emit merging code for each of the fields we processed. - bool deferred_has_bit_changes = false; for (const auto* field : fields) { const auto& generator = field_generators_.get(field); @@ -3619,10 +3735,6 @@ void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* p) { format.Indent(); if (check_has_byte && IsPOD(field)) { - // Defer hasbit modification until the end of chunk. - // This can reduce the number of loads/stores by up to 7 per 8 - // fields. - deferred_has_bit_changes = true; generator.GenerateCopyConstructorCode(p); } else { generator.GenerateMergingCode(p); @@ -3634,13 +3746,6 @@ void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* p) { } if (check_has_byte) { - if (deferred_has_bit_changes) { - // Flush the has bits for the primitives we deferred. - ABSL_CHECK_LE(0, cached_has_word_index); - format("_this->$has_bits$[$1$] |= cached_has_bits;\n", - cached_has_word_index); - } - format.Outdent(); format("}\n"); } @@ -3660,25 +3765,58 @@ void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* p) { } } + if (HasBitsSize() == 1) { + // Optimization to avoid a load. Assuming that most messages have fewer than + // 32 fields, this seems useful. + p->Emit(R"cc( + _this->$has_bits$[0] |= cached_has_bits; + )cc"); + } else if (HasBitsSize() > 1) { + p->Emit(R"cc( + _this->$has_bits$.Or(from.$has_bits$); + )cc"); + } + // Merge oneof fields. Oneof field requires oneof case check. for (auto oneof : OneOfRange(descriptor_)) { - format("switch (from.$1$_case()) {\n", oneof->name()); - format.Indent(); - for (auto field : FieldRange(oneof)) { - format("case k$1$: {\n", UnderscoresToCamelCase(field->name(), true)); - format.Indent(); - field_generators_.get(field).GenerateMergingCode(p); - format("break;\n"); - format.Outdent(); - format("}\n"); - } - format( - "case $1$_NOT_SET: {\n" - " break;\n" - "}\n", - absl::AsciiStrToUpper(oneof->name())); - format.Outdent(); - format("}\n"); + p->Emit({{"name", oneof->name()}, + {"NAME", absl::AsciiStrToUpper(oneof->name())}, + {"index", oneof->index()}, + {"cases", + [&] { + for (const auto* field : FieldRange(oneof)) { + p->Emit( + {{"Label", UnderscoresToCamelCase(field->name(), true)}, + {"body", + [&] { + field_generators_.get(field).GenerateMergingCode(p); + }}}, + R"cc( + case k$Label$: { + $body$; + break; + } + )cc"); + } + }}}, + R"cc( + if (const uint32_t oneof_from_case = from.$oneof_case$[$index$]) { + const uint32_t oneof_to_case = _this->$oneof_case$[$index$]; + const bool oneof_needs_init = oneof_to_case != oneof_from_case; + if (oneof_needs_init) { + if (oneof_to_case != 0) { + _this->clear_$name$(); + } + _this->$oneof_case$[$index$] = oneof_from_case; + } + + switch (oneof_from_case) { + $cases$; + case $NAME$_NOT_SET: + break; + } + } + )cc"); } if (num_weak_fields_) { format( @@ -3932,9 +4070,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody(io::Printer* p) { class LazySerializerEmitter { public: LazySerializerEmitter(MessageGenerator* mg, io::Printer* p) - : mg_(mg), - p_(p), - cached_has_bit_index_(kNoHasbit) {} + : mg_(mg), p_(p), cached_has_bit_index_(kNoHasbit) {} ~LazySerializerEmitter() { Flush(); } @@ -4134,7 +4270,6 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody(io::Printer* p) { void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled( io::Printer* p) { - std::vector ordered_fields = SortFieldsByNumber(descriptor_); diff --git a/src/google/protobuf/compiler/cpp/message.h b/src/google/protobuf/compiler/cpp/message.h index 4c404adcb9..f16cd43590 100644 --- a/src/google/protobuf/compiler/cpp/message.h +++ b/src/google/protobuf/compiler/cpp/message.h @@ -12,6 +12,7 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__ #define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__ +#include #include #include #include @@ -20,6 +21,7 @@ #include #include "absl/container/flat_hash_map.h" +#include "absl/strings/string_view.h" #include "google/protobuf/compiler/cpp/enum.h" #include "google/protobuf/compiler/cpp/extension.h" #include "google/protobuf/compiler/cpp/field.h" @@ -80,6 +82,7 @@ class MessageGenerator { const Descriptor* descriptor() const { return descriptor_; } private: + using GeneratorFunction = FieldGeneratorBase::GeneratorFunction; enum class InitType { kConstexpr, kArena, kArenaCopy }; // Generate declarations and definitions of accessors for fields. @@ -118,6 +121,9 @@ class MessageGenerator { void GenerateSerializeWithCachedSizesBodyShuffled(io::Printer* p); void GenerateByteSize(io::Printer* p); void GenerateClassData(io::Printer* p); + void GenerateMapEntryClassDefinition(io::Printer* p); + void GenerateAnyMethodDefinition(io::Printer* p); + void GenerateImplDefinition(io::Printer* p); void GenerateMergeFrom(io::Printer* p); void GenerateClassSpecificMergeImpl(io::Printer* p); void GenerateCopyFrom(io::Printer* p); @@ -148,6 +154,10 @@ class MessageGenerator { void GenerateFieldClear(const FieldDescriptor* field, bool is_inline, io::Printer* p); + // Returns true if any of the fields needs an `arena` variable containing + // the current message's arena, reducing `GetArena()` call churn. + bool RequiresArena(GeneratorFunction function) const; + // Returns whether impl_ has a copy ctor. bool ImplHasCopyCtor() const; diff --git a/src/google/protobuf/compiler/cpp/options.h b/src/google/protobuf/compiler/cpp/options.h index 5ae95353fb..4d6006372e 100644 --- a/src/google/protobuf/compiler/cpp/options.h +++ b/src/google/protobuf/compiler/cpp/options.h @@ -50,10 +50,12 @@ struct Options { bool transitive_pb_h = true; bool annotate_headers = false; bool lite_implicit_weak_fields = false; + bool descriptor_implicit_weak_messages = false; bool bootstrap = false; bool opensource_runtime = false; bool annotate_accessor = false; bool force_split = false; + bool profile_driven_cluster_aux_subtable = false; #ifdef PROTOBUF_STABLE_EXPERIMENTS bool force_eagerly_verified_lazy = true; bool force_inline_string = true; diff --git a/src/google/protobuf/compiler/cpp/parse_function_generator.cc b/src/google/protobuf/compiler/cpp/parse_function_generator.cc index 6fb3aa85e3..3f511116d4 100644 --- a/src/google/protobuf/compiler/cpp/parse_function_generator.cc +++ b/src/google/protobuf/compiler/cpp/parse_function_generator.cc @@ -116,11 +116,9 @@ ParseFunctionGenerator::ParseFunctionGenerator( if (should_generate_tctable()) { tc_table_info_.reset(new TailCallTableInfo( descriptor_, ordered_fields_, - { - /* is_lite */ GetOptimizeFor(descriptor->file(), options_) == - FileOptions::LITE_RUNTIME, - /* uses_codegen */ true, - }, + {/* is_lite */ GetOptimizeFor(descriptor->file(), options_) == + FileOptions::LITE_RUNTIME, + /* uses_codegen */ true, options_.profile_driven_cluster_aux_subtable}, GeneratedOptionProvider(this), has_bit_indices, inlined_string_indices)); } @@ -403,9 +401,29 @@ void ParseFunctionGenerator::GenerateTailCallTable(io::Printer* printer) { } format( "&$1$._instance,\n" - "$2$, // fallback\n" - "", + "$2$, // fallback\n", DefaultInstanceName(descriptor_, options_), fallback); + std::vector subtable_fields; + for (const auto& aux : tc_table_info_->aux_entries) { + if (aux.type == internal::TailCallTableInfo::kSubTable) { + subtable_fields.push_back(aux.field); + } + } + const auto* hottest = FindHottestField(subtable_fields, options_); + // We'll prefetch `to_prefetch->to_prefetch` unconditionally to avoid + // branches. Set the pointer to itself to avoid nullptr. + printer->Emit( + {{"hottest_type_name", + QualifiedClassName( + hottest == nullptr ? descriptor_ : hottest->message_type(), + options_)}}, + // clang-format off + R"cc( +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE +::_pbi::TcParser::GetTable<$hottest_type_name$>(), // to_prefetch +#endif // PROTOBUF_PREFETCH_PARSE_TABLE + )cc"); + // clang-format on } format("}, {{\n"); { @@ -623,141 +641,6 @@ void ParseFunctionGenerator::GenerateFastFieldEntries(Formatter& format) { } } -static void FormatFieldKind(Formatter& format, - const TailCallTableInfo::FieldEntryInfo& entry) { - // In here we convert the runtime value of entry.type_card back into a - // sequence of literal enum labels. We use the mnenonic labels for nicer - // codegen. - namespace fl = internal::field_layout; - const uint16_t type_card = entry.type_card; - const int rep_index = (type_card & fl::kRepMask) >> fl::kRepShift; - const int tv_index = (type_card & fl::kTvMask) >> fl::kTvShift; - - // Use `0|` prefix to eagerly convert the enums to int to avoid enum-enum - // operations. They are deprecated in C++20. - format("(0 | "); - static constexpr const char* kFieldCardNames[] = {"Singular", "Optional", - "Repeated", "Oneof"}; - static_assert((fl::kFcSingular >> fl::kFcShift) == 0, ""); - static_assert((fl::kFcOptional >> fl::kFcShift) == 1, ""); - static_assert((fl::kFcRepeated >> fl::kFcShift) == 2, ""); - static_assert((fl::kFcOneof >> fl::kFcShift) == 3, ""); - - format("::_fl::kFc$1$", - kFieldCardNames[(type_card & fl::kFcMask) >> fl::kFcShift]); - -#define PROTOBUF_INTERNAL_TYPE_CARD_CASE(x) \ - case fl::k##x: \ - format(" | ::_fl::k" #x); \ - break - - switch (type_card & fl::kFkMask) { - case fl::kFkString: { - switch (type_card & ~fl::kFcMask & ~fl::kRepMask & ~fl::kSplitMask) { - PROTOBUF_INTERNAL_TYPE_CARD_CASE(Bytes); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(RawString); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(Utf8String); - default: - ABSL_LOG(FATAL) << "Unknown type_card: 0x" << type_card; - } - - static constexpr const char* kRepNames[] = {"AString", "IString", "Cord", - "SPiece", "SString"}; - static_assert((fl::kRepAString >> fl::kRepShift) == 0, ""); - static_assert((fl::kRepIString >> fl::kRepShift) == 1, ""); - static_assert((fl::kRepCord >> fl::kRepShift) == 2, ""); - static_assert((fl::kRepSPiece >> fl::kRepShift) == 3, ""); - static_assert((fl::kRepSString >> fl::kRepShift) == 4, ""); - - format(" | ::_fl::kRep$1$", kRepNames[rep_index]); - break; - } - - case fl::kFkMessage: { - format(" | ::_fl::kMessage"); - - static constexpr const char* kRepNames[] = {nullptr, "Group", "Lazy"}; - static_assert((fl::kRepGroup >> fl::kRepShift) == 1, ""); - static_assert((fl::kRepLazy >> fl::kRepShift) == 2, ""); - - if (auto* rep = kRepNames[rep_index]) { - format(" | ::_fl::kRep$1$", rep); - } - - static constexpr const char* kXFormNames[2][4] = { - {nullptr, "Default", "Table", "WeakPtr"}, {nullptr, "Eager", "Lazy"}}; - - static_assert((fl::kTvDefault >> fl::kTvShift) == 1, ""); - static_assert((fl::kTvTable >> fl::kTvShift) == 2, ""); - static_assert((fl::kTvWeakPtr >> fl::kTvShift) == 3, ""); - static_assert((fl::kTvEager >> fl::kTvShift) == 1, ""); - static_assert((fl::kTvLazy >> fl::kTvShift) == 2, ""); - - if (auto* xform = kXFormNames[rep_index == 2][tv_index]) { - format(" | ::_fl::kTv$1$", xform); - } - break; - } - - case fl::kFkMap: - format(" | ::_fl::kMap"); - break; - - case fl::kFkNone: - break; - - case fl::kFkVarint: - case fl::kFkPackedVarint: - case fl::kFkFixed: - case fl::kFkPackedFixed: { - switch (type_card & ~fl::kFcMask & ~fl::kSplitMask) { - PROTOBUF_INTERNAL_TYPE_CARD_CASE(Bool); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(Fixed32); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(UInt32); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(SFixed32); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(Int32); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(SInt32); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(Float); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(Enum); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(EnumRange); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(OpenEnum); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(Fixed64); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(UInt64); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(SFixed64); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(Int64); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(SInt64); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(Double); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedBool); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedFixed32); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedUInt32); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedSFixed32); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedInt32); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedSInt32); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedFloat); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedEnum); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedEnumRange); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedOpenEnum); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedFixed64); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedUInt64); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedSFixed64); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedInt64); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedSInt64); - PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedDouble); - default: - ABSL_LOG(FATAL) << "Unknown type_card: 0x" << type_card; - } - } - } - - if (type_card & fl::kSplitMask) { - format(" | ::_fl::kSplitTrue"); - } - -#undef PROTOBUF_INTERNAL_TYPE_CARD_CASE - - format(")"); -} - void ParseFunctionGenerator::GenerateFieldEntries(Formatter& format) { for (const auto& entry : tc_table_info_->field_entries) { const FieldDescriptor* field = entry.field; @@ -789,7 +672,9 @@ void ParseFunctionGenerator::GenerateFieldEntries(Formatter& format) { format("0, "); } format("$1$,\n ", entry.aux_idx); - FormatFieldKind(format, entry); + // Use `0|` prefix to eagerly convert the enums to int to avoid enum-enum + // operations. They are deprecated in C++20. + format("(0 | $1$)", internal::TypeCardToString(entry.type_card)); } format("},\n"); } diff --git a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.cc b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.cc index 8af6b57380..5621d1922b 100644 --- a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.cc +++ b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.cc @@ -16,8 +16,11 @@ #include #include +#include "google/protobuf/testing/fileenums.h" #include "google/protobuf/testing/file.h" #include "google/protobuf/testing/file.h" +#include "google/protobuf/testing/path.h" +#include "file/util/fileyielder.h" #include "google/protobuf/compiler/access_info_map.h" #include "google/protobuf/compiler/split_map.h" #include "google/protobuf/compiler/profile_bootstrap.pb.h" @@ -26,6 +29,8 @@ #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/cord.h" +#include "absl/strings/match.h" +#include "absl/strings/str_cat.h" #include "absl/strings/str_replace.h" #include "absl/strings/string_view.h" #include "google/protobuf/compiler/cpp/cpp_access_info_parse_helper.h" @@ -42,15 +47,19 @@ namespace tools { namespace { -enum PDProtoScale { kNever, kRarely, kDefault, kLikely }; +enum PDProtoScale { kInvalid, kNever, kRarely, kDefault, kLikely }; struct PDProtoAnalysis { PDProtoScale presence = PDProtoScale::kDefault; PDProtoScale usage = PDProtoScale::kDefault; + uint64_t presence_count = 0; + uint64_t usage_count = 0; }; std::ostream& operator<<(std::ostream& s, PDProtoScale scale) { switch (scale) { + case PDProtoScale::kInvalid: + return s << "INVALID"; case PDProtoScale::kNever: return s << "NEVER"; case PDProtoScale::kRarely: @@ -106,18 +115,26 @@ class PDProtoAnalyzer { PDProtoAnalysis AnalyzeField(const FieldDescriptor* field) { PDProtoAnalysis analysis; - if (info_map_.InProfile(field)) { - if (IsLikelyPresent(field)) { - analysis.presence = PDProtoScale::kLikely; - } else if (IsRarelyPresent(field)) { - analysis.presence = PDProtoScale::kRarely; - } + if (!info_map_.InProfile(field)) { + return analysis; } - if (info_map_.InProfile(field) && - info_map_.AccessCount(field, AccessInfoMap::kReadWriteOther) <= - info_map_.GetUnlikelyUsedThreshold()) { - analysis.usage = PDProtoScale::kRarely; + if (IsLikelyPresent(field)) { + analysis.presence = PDProtoScale::kLikely; + } else if (IsRarelyPresent(field)) { + analysis.presence = PDProtoScale::kRarely; + } + analysis.presence_count = + info_map_.AccessCount(field, AccessInfoMap::kReadWrite); + + if (!info_map_.HasUsage(field)) { + analysis.usage = PDProtoScale ::kInvalid; + } else { + analysis.usage_count = + info_map_.AccessCount(field, AccessInfoMap::kReadWriteOther); + if (analysis.usage_count <= info_map_.GetUnlikelyUsedThreshold()) { + analysis.usage = PDProtoScale::kRarely; + } } return analysis; @@ -273,9 +290,102 @@ std::vector SortMessages( return sorted; } +struct Stats { + uint64_t singular_total_pcount = 0; + uint64_t repeated_total_pcount = 0; + uint64_t singular_lazy_pcount = 0; + uint64_t singular_lazy_0usage_pcount = 0; + uint64_t repeated_lazy_pcount = 0; + uint64_t singular_lazy_num = 0; + uint64_t singular_lazy_0usage_num = 0; + uint64_t repeated_lazy_num = 0; + uint64_t max_pcount = 0; + uint64_t max_ucount = 0; +}; + +void Aggregate(const FieldDescriptor* field, const PDProtoAnalysis& analysis, + const PDProtoOptimization& optimized, Stats& stats) { + if (stats.max_pcount < analysis.presence_count) { + stats.max_pcount = analysis.presence_count; + } + if (stats.max_ucount < analysis.usage_count) { + stats.max_ucount = analysis.usage_count; + } + if (field->type() == FieldDescriptor::TYPE_MESSAGE) { + if (field->is_repeated()) { + stats.repeated_total_pcount += analysis.presence_count; + } else { + stats.singular_total_pcount += analysis.presence_count; + } + } + if (optimized == kLazy) { + if (field->is_repeated()) { + stats.repeated_lazy_num++; + stats.repeated_lazy_pcount += analysis.presence_count; + } else { + stats.singular_lazy_num++; + stats.singular_lazy_pcount += analysis.presence_count; + if (analysis.usage_count == 0) { + stats.singular_lazy_0usage_num++; + stats.singular_lazy_0usage_pcount += analysis.presence_count; + } + } + } +} + +void Aggregate(const Stats& in, Stats& out) { + out.singular_total_pcount += in.singular_total_pcount; + out.repeated_total_pcount += in.repeated_total_pcount; + out.singular_lazy_num += in.singular_lazy_num; + out.singular_lazy_0usage_num += in.singular_lazy_0usage_num; + out.repeated_lazy_num += in.repeated_lazy_num; + out.singular_lazy_pcount += in.singular_lazy_pcount; + out.singular_lazy_0usage_pcount += in.singular_lazy_0usage_pcount; + out.repeated_lazy_pcount += in.repeated_lazy_pcount; + out.max_pcount = std::max(out.max_pcount, in.max_pcount); + out.max_ucount = std::max(out.max_ucount, in.max_ucount); +} + +std::ostream& operator<<(std::ostream& s, Stats stats) { + s << "========" << std::endl + << "singular_lazy_num=" << stats.singular_lazy_num << std::endl + << "singular_lazy_0usage_num=" << stats.singular_lazy_0usage_num + << std::endl + << "repeated_lazy_num=" << stats.repeated_lazy_num << std::endl + << "singular_total_pcount=" << stats.singular_total_pcount << std::endl + << "repeated_total_pcount=" << stats.repeated_total_pcount << std::endl + << "singular_lazy_pcount=" << stats.singular_lazy_pcount << std::endl + << "singular_lazy_0usage_pcount=" << stats.singular_lazy_0usage_pcount + << std::endl + << "repeated_lazy_pcount=" << stats.repeated_lazy_pcount << std::endl + << "max_pcount=" << stats.max_pcount << std::endl + << "max_ucount=" << stats.max_ucount << std::endl + << "repeated_lazy_num/singular_lazy_num=" + << static_cast(stats.repeated_lazy_num) / + static_cast(stats.singular_lazy_num) + << std::endl + << "repeated_lazy_pcount/singular_lazy_pcount=" + << static_cast(stats.repeated_lazy_pcount) / + static_cast(stats.singular_lazy_pcount) + << std::endl + << "singular_lazy_pcount/singular_total_pcount=" + << static_cast(stats.singular_lazy_pcount) / + static_cast(stats.singular_total_pcount) + << std::endl + << "singular_lazy_0usage_pcount/singular_total_pcount=" + << static_cast(stats.singular_lazy_0usage_pcount) / + static_cast(stats.singular_total_pcount) + << std::endl + << "repeated_lazy_pcount/repeated_total_pcount=" + << static_cast(stats.repeated_lazy_pcount) / + static_cast(stats.repeated_total_pcount) + << std::endl; + return s; +} + } // namespace -absl::Status AnalyzeProfileProtoToText( +static absl::StatusOr AnalyzeProfileProto( std::ostream& stream, absl::string_view proto_profile, const AnalyzeProfileProtoOptions& options) { if (options.pool == nullptr) { @@ -300,6 +410,7 @@ absl::Status AnalyzeProfileProtoToText( << "-----------------------------------------\n"; } + Stats stats; for (const MessageAccessInfo* message : SortMessages(*access_info)) { if (RE2::PartialMatch(message->name(), regex)) { if (const Descriptor* descriptor = @@ -311,8 +422,10 @@ absl::Status AnalyzeProfileProtoToText( const FieldDescriptor* field = descriptor->field(i); PDProtoAnalysis analysis = analyzer.AnalyzeField(field); PDProtoOptimization optimized = analyzer.OptimizeField(field); + Aggregate(field, analysis, optimized, stats); if (options.print_all_fields || options.print_analysis || - optimized != PDProtoOptimization::kNone) { + (options.print_optimized && + (optimized != PDProtoOptimization::kNone))) { if (!message_header) { message_header = true; stream << "Message " @@ -340,6 +453,39 @@ absl::Status AnalyzeProfileProtoToText( } } } + if (options.print_analysis) { + stream << stats; + } + return stats; +} + +absl::Status AnalyzeProfileProtoToText( + std::ostream& stream, absl::string_view proto_profile, + const AnalyzeProfileProtoOptions& options) { + return AnalyzeProfileProto(stream, proto_profile, options).status(); +} + +absl::Status AnalyzeAndAggregateProfileProtosToText( + std::ostream& stream, absl::string_view root, + const AnalyzeProfileProtoOptions& options) { + FileYielder yielder; + int errors = 0; + yielder.Start({file::JoinPath(root, "*")}, file::MATCH_DEFAULT, + /*recursively_expand=*/true, &errors); + if (errors > 0) { + return absl::InternalError(absl::StrCat("Failed to traverse path: ", root)); + } + Stats merged; + for (; !yielder.Done(); yielder.Next()) { + const std::string& full_path = yielder.FullPathName(); + if (!absl::EndsWith(full_path, "proto.profile")) { + continue; + } + stream << full_path << std::endl; + auto stats = *AnalyzeProfileProto(stream, full_path, options); + Aggregate(stats, merged); + } + stream << merged; return absl::OkStatus(); } diff --git a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.h b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.h index f80bf5c9eb..289d294415 100644 --- a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.h +++ b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto.h @@ -17,6 +17,9 @@ struct AnalyzeProfileProtoOptions { // true to print the 'unlikely used' threshold. bool print_unused_threshold = true; + // true to print the PDProto optimizations that would be applied to the field. + bool print_optimized = true; + // true to print all fields instead of optimized fields only. bool print_all_fields = false; @@ -30,10 +33,17 @@ struct AnalyzeProfileProtoOptions { std::string message_filter; }; +// Prints analysis for the given proto profile. absl::Status AnalyzeProfileProtoToText( std::ostream& stream, absl::string_view proto_profile, const AnalyzeProfileProtoOptions& options); +// Prints aggregated analysis for the proto profiles under the given root +// directory. +absl::Status AnalyzeAndAggregateProfileProtosToText( + std::ostream& stream, absl::string_view root, + const AnalyzeProfileProtoOptions& options); + } // namespace tools } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_main.cc b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_main.cc index 4b9035abfe..b0756a3977 100644 --- a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_main.cc +++ b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_main.cc @@ -4,6 +4,14 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd +// +// This tool takes a PDProto profile as input and prints out the analysis, such +// as the PDProto optimizations that would be applied based on the given +// profile. +// +// It can also take a directory as input and print out the aggregated analysis +// for all the PDProto profiles under the directory. This is useful when we want +// to get some statistics for the fleet. #include #include @@ -19,6 +27,9 @@ ABSL_FLAG(bool, all, false, "Print all fields"); ABSL_FLAG(bool, analysis, false, "Print field analysis"); ABSL_FLAG(std::string, message_filter, "", "Regex match for message name"); +ABSL_FLAG(bool, aggregate_analysis, false, + "If set, will recursively find proto.profile in the given dir and " + "print the aggregated analysis. Will not print individual analysis."); int main(int argc, char* argv[]) { using google::protobuf::compiler::tools::AnalyzeProfileProtoOptions; @@ -30,10 +41,18 @@ int main(int argc, char* argv[]) { google::protobuf::DescriptorPool pool(google::protobuf::util::globaldb::global()); AnalyzeProfileProtoOptions options; options.pool = &pool; - options.print_all_fields = absl::GetFlag(FLAGS_all); - options.print_analysis = absl::GetFlag(FLAGS_analysis); - options.message_filter = absl::GetFlag(FLAGS_message_filter); - absl::Status status = AnalyzeProfileProtoToText(std::cout, argv[1], options); + absl::Status status; + if (!absl::GetFlag(FLAGS_aggregate_analysis)) { + options.print_all_fields = absl::GetFlag(FLAGS_all); + options.print_analysis = absl::GetFlag(FLAGS_analysis); + options.message_filter = absl::GetFlag(FLAGS_message_filter); + status = AnalyzeProfileProtoToText(std::cout, argv[1], options); + } else { + options.print_unused_threshold = false; + options.print_optimized = false; + status = + AnalyzeAndAggregateProfileProtosToText(std::cout, argv[1], options); + } if (!status.ok()) { ABSL_LOG(ERROR) << status; return 2; diff --git a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.cc b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.cc index 04ebbf1c51..31a1e7aaee 100644 --- a/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.cc +++ b/src/google/protobuf/compiler/cpp/tools/analyze_profile_proto_test.cc @@ -137,6 +137,52 @@ TEST(AnalyzeProfileProtoTest, NestedCppNameMatchedToPoolName) { " string optional_string: INLINE\n"); } +TEST(AnalyzeProfileProtoTest, PrintStatistics) { + AccessInfo info = ParseTextOrDie(R"pb( + language: "cpp" + message { + name: "google::protobuf::compiler::tools::AnalyzeThis" + count: 100 + field { name: "id" getters_count: 1 configs_count: 100 } + field { name: "optional_string" getters_count: 1 configs_count: 100 } + field { name: "optional_child" getters_count: 100 configs_count: 1 } + field { name: "repeated_string" getters_count: 100 configs_count: 100 } + field { name: "repeated_child" getters_count: 100 configs_count: 100 } + field { name: "nested" getters_count: 1 configs_count: 100 } + } + )pb"); + AnalyzeProfileProtoOptions options; + options.print_unused_threshold = false; + options.print_optimized = false; + options.print_analysis = true; + options.pool = DescriptorPool::generated_pool(); + EXPECT_STREQ(AnalyzeToText(info, options).c_str(), + R"(Message google::protobuf::compiler::tools::AnalyzeThis + int32 id: RARELY_USED + string optional_string: RARELY_USED + string[] repeated_string: LIKELY_PRESENT RARELY_USED + AnalyzeChild optional_child: LIKELY_PRESENT RARELY_USED LAZY + AnalyzeChild[] repeated_child: LIKELY_PRESENT RARELY_USED + Nested nested: RARELY_USED +======== +singular_lazy_num=1 +singular_lazy_0usage_num=0 +repeated_lazy_num=0 +singular_total_pcount=101 +repeated_total_pcount=100 +singular_lazy_pcount=100 +singular_lazy_0usage_pcount=0 +repeated_lazy_pcount=0 +max_pcount=100 +max_ucount=100 +repeated_lazy_num/singular_lazy_num=0 +repeated_lazy_pcount/singular_lazy_pcount=0 +singular_lazy_pcount/singular_total_pcount=0.990099 +singular_lazy_0usage_pcount/singular_total_pcount=0 +repeated_lazy_pcount/repeated_total_pcount=0 +)"); +} + } // namespace } // namespace tools } // namespace compiler diff --git a/src/google/protobuf/compiler/cpp/unittest.inc b/src/google/protobuf/compiler/cpp/unittest.inc index 169fbb6021..56109d3913 100644 --- a/src/google/protobuf/compiler/cpp/unittest.inc +++ b/src/google/protobuf/compiler/cpp/unittest.inc @@ -926,7 +926,6 @@ TEST(GENERATED_MESSAGE_TEST_NAME, TestOneofSpaceUsed) { #endif // !PROTOBUF_TEST_NO_DESCRIPTORS TEST(GENERATED_MESSAGE_TEST_NAME, FieldConstantValues) { - UNITTEST::TestRequired message; EXPECT_EQ(UNITTEST::TestAllTypes_NestedMessage::kBbFieldNumber, 1); EXPECT_EQ(UNITTEST::TestAllTypes::kOptionalInt32FieldNumber, 1); EXPECT_EQ(UNITTEST::TestAllTypes::kOptionalgroupFieldNumber, 16); diff --git a/src/google/protobuf/compiler/java/BUILD.bazel b/src/google/protobuf/compiler/java/BUILD.bazel index 8ca67c1bbb..bac4587304 100644 --- a/src/google/protobuf/compiler/java/BUILD.bazel +++ b/src/google/protobuf/compiler/java/BUILD.bazel @@ -37,9 +37,9 @@ cc_library( visibility = ["//pkg:__pkg__"], deps = [ ":java_features_bootstrap", - "//src/google/protobuf:descriptor_legacy", "//src/google/protobuf:protobuf_nowkt", "//src/google/protobuf/compiler:code_generator", + "//src/google/protobuf/compiler:versions", "@com_google_absl//absl/container:flat_hash_set", ], ) @@ -129,7 +129,6 @@ cc_library( ":names", ":names_internal", "//src/google/protobuf:arena", - "//src/google/protobuf:descriptor_legacy", "//src/google/protobuf:protobuf_nowkt", "//src/google/protobuf/compiler:code_generator", "//src/google/protobuf/compiler:retention", diff --git a/src/google/protobuf/compiler/java/file.cc b/src/google/protobuf/compiler/java/file.cc index 5401e8257b..0afaa47f71 100644 --- a/src/google/protobuf/compiler/java/file.cc +++ b/src/google/protobuf/compiler/java/file.cc @@ -273,6 +273,14 @@ void FileGenerator::Generate(io::Printer* printer) { printer->Annotate("classname", file_->name()); printer->Indent(); + if (options_.opensource_runtime) { + printer->Print("static {\n"); + printer->Indent(); + PrintGencodeVersionValidator(printer); + printer->Outdent(); + printer->Print("}\n"); + } + // ----------------------------------------------------------------- printer->Print( diff --git a/src/google/protobuf/compiler/java/helpers.cc b/src/google/protobuf/compiler/java/helpers.cc index c457370cfc..55b38c1d75 100644 --- a/src/google/protobuf/compiler/java/helpers.cc +++ b/src/google/protobuf/compiler/java/helpers.cc @@ -28,8 +28,9 @@ #include "absl/strings/string_view.h" #include "absl/strings/substitute.h" #include "google/protobuf/compiler/java/name_resolver.h" +#include "google/protobuf/compiler/versions.h" #include "google/protobuf/descriptor.pb.h" -#include "google/protobuf/descriptor_legacy.h" +#include "google/protobuf/io/printer.h" #include "google/protobuf/io/strtod.h" #include "google/protobuf/wire_format.h" @@ -41,8 +42,8 @@ namespace protobuf { namespace compiler { namespace java { -using internal::WireFormat; -using internal::WireFormatLite; +using ::google::protobuf::internal::WireFormat; +using ::google::protobuf::internal::WireFormatLite; const char kThickSeparator[] = "// ===================================================================\n"; @@ -84,6 +85,21 @@ void PrintEnumVerifierLogic( absl::StrCat(enum_verifier_string, terminating_string)); } +void PrintGencodeVersionValidator(io::Printer* printer) { + const auto& version = GetProtobufJavaVersion(); + printer->Print( + "com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion(\n" + " com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC,\n" + " $major$,\n" + " $minor$,\n" + " $patch$,\n" + " $suffix$);\n", + "major", absl::StrCat("/* major= */ ", version.major()), "minor", + absl::StrCat("/* minor= */ ", version.minor()), "patch", + absl::StrCat("/* patch= */ ", version.patch()), "suffix", + absl::StrCat("/* suffix= */ \"", version.suffix(), "\"")); +} + std::string UnderscoresToCamelCase(absl::string_view input, bool cap_next_letter) { ABSL_CHECK(!input.empty()); @@ -811,8 +827,7 @@ bool HasRequiredFields(const Descriptor* type) { } bool IsRealOneof(const FieldDescriptor* descriptor) { - return descriptor->containing_oneof() && - !OneofDescriptorLegacy(descriptor->containing_oneof()).is_synthetic(); + return descriptor->real_containing_oneof(); } bool HasRepeatedFields(const Descriptor* descriptor) { diff --git a/src/google/protobuf/compiler/java/helpers.h b/src/google/protobuf/compiler/java/helpers.h index 8dc75a9ed3..60f963ac68 100644 --- a/src/google/protobuf/compiler/java/helpers.h +++ b/src/google/protobuf/compiler/java/helpers.h @@ -22,7 +22,6 @@ #include "google/protobuf/compiler/java/options.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" -#include "google/protobuf/descriptor_legacy.h" #include "google/protobuf/io/printer.h" // Must be last. @@ -60,6 +59,10 @@ void PrintEnumVerifierLogic( absl::string_view var_name, absl::string_view terminating_string, bool enforce_lite); +// Prints the Protobuf Java Version validator checking that the runtime and +// gencode versions are compatible. +void PrintGencodeVersionValidator(io::Printer* printer); + // Converts a name to camel-case. If cap_first_letter is true, capitalize the // first letter. std::string ToCamelCase(absl::string_view input, bool lower_first); @@ -340,13 +343,6 @@ inline bool HasHasbit(const FieldDescriptor* descriptor) { return internal::cpp::HasHasbit(descriptor); } -// Whether generate classes expose public PARSER instances. -inline bool ExposePublicParser(const FileDescriptor* descriptor) { - // TODO: Mark the PARSER private in 3.1.x releases. - return FileDescriptorLegacy(descriptor).syntax() == - FileDescriptorLegacy::Syntax::SYNTAX_PROTO2; -} - // Whether unknown enum values are kept (i.e., not stored in UnknownFieldSet // but in the message and can be queried using additional getters that return // ints. diff --git a/src/google/protobuf/compiler/java/java_features.pb.cc b/src/google/protobuf/compiler/java/java_features.pb.cc index 309375292d..2a632e7eb4 100644 --- a/src/google/protobuf/compiler/java/java_features.pb.cc +++ b/src/google/protobuf/compiler/java/java_features.pb.cc @@ -1,5 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/compiler/java/java_features.proto +// Protobuf C++ Version: 4.26.0-dev #include "google/protobuf/compiler/java/java_features.pb.h" @@ -122,9 +123,6 @@ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fja PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto; } -// Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 -static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto(&descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto); namespace pb { const ::google::protobuf::EnumDescriptor* JavaFeatures_Utf8Validation_descriptor() { ::google::protobuf::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto); @@ -154,12 +152,6 @@ class JavaFeatures::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(JavaFeatures, _impl_._has_bits_); - static void set_has_legacy_closed_enum(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_utf8_validation(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } }; JavaFeatures::JavaFeatures(::google::protobuf::Arena* arena) @@ -199,12 +191,13 @@ inline void JavaFeatures::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* JavaFeatures::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { JavaFeatures::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(JavaFeatures, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void JavaFeatures::Clear() { // @@protoc_insertion_point(message_clear_start:pb.JavaFeatures) @@ -244,6 +237,9 @@ const ::_pbi::TcParseTable<1, 2, 1, 0, 2> JavaFeatures::_table_ = { offsetof(decltype(_table_), aux_entries), &_JavaFeatures_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::pb::JavaFeatures>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // optional .pb.JavaFeatures.Utf8Validation utf8_validation = 2 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { {::_pbi::TcParser::FastEr0S1, @@ -323,7 +319,7 @@ const ::_pbi::TcParseTable<1, 2, 1, 0, 2> JavaFeatures::_table_ = { } -void JavaFeatures::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void JavaFeatures::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:pb.JavaFeatures) @@ -339,8 +335,8 @@ void JavaFeatures::MergeImpl(::google::protobuf::Message& to_msg, const ::google if (cached_has_bits & 0x00000002u) { _this->_impl_.utf8_validation_ = from._impl_.utf8_validation_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -355,9 +351,6 @@ PROTOBUF_NOINLINE bool JavaFeatures::IsInitialized() const { return true; } -::_pbi::CachedSize* JavaFeatures::AccessCachedSize() const { - return &_impl_._cached_size_; -} void JavaFeatures::InternalSwap(JavaFeatures* PROTOBUF_RESTRICT other) { using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); @@ -371,13 +364,15 @@ void JavaFeatures::InternalSwap(JavaFeatures* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata JavaFeatures::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_once, - file_level_metadata_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto[0]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_once, + file_level_metadata_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto[0]); } -PROTOC_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::FeatureSet, - ::google::protobuf::internal::MessageTypeTraits< ::pb::JavaFeatures >, 11, false> - java(kJavaFieldNumber, ::pb::JavaFeatures::default_instance(), nullptr); +PROTOBUF_CONSTINIT PROTOC_EXPORT + PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi:: + ExtensionIdentifier<::google::protobuf::FeatureSet, ::_pbi::MessageTypeTraits< ::pb::JavaFeatures >, + 11, false> + java(kJavaFieldNumber, &::pb::_JavaFeatures_default_instance_); // @@protoc_insertion_point(namespace_scope) } // namespace pb namespace google { @@ -385,4 +380,12 @@ namespace protobuf { } // namespace protobuf } // namespace google // @@protoc_insertion_point(global_scope) +PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 +static ::std::false_type _static_init_ PROTOBUF_UNUSED = + (::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto), + ::_pbi::ExtensionSet::RegisterMessageExtension( + &::google::protobuf::FeatureSet::default_instance(), 1001, 11, + false, false, &::pb::JavaFeatures::default_instance(), + nullptr, ::_pbi::LazyAnnotation::kUndefined), + ::std::false_type{}); #include "google/protobuf/port_undef.inc" diff --git a/src/google/protobuf/compiler/java/java_features.pb.h b/src/google/protobuf/compiler/java/java_features.pb.h index 1a0c7bba2e..aca9f50c3a 100644 --- a/src/google/protobuf/compiler/java/java_features.pb.h +++ b/src/google/protobuf/compiler/java/java_features.pb.h @@ -1,6 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/compiler/java/java_features.proto -// Protobuf C++ Version: 4.24.0-main +// Protobuf C++ Version: 4.26.0-dev #ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_2epb_2eh #define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_2epb_2eh @@ -11,17 +11,11 @@ #include #include "google/protobuf/port_def.inc" -#if PROTOBUF_VERSION < 4024000 -#error "This file was generated by a newer version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please update" -#error "your headers." -#endif // PROTOBUF_VERSION - -#if 4024000 < PROTOBUF_MIN_PROTOC_VERSION -#error "This file was generated by an older version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please" -#error "regenerate this file with a newer version of protoc." -#endif // PROTOBUF_MIN_PROTOC_VERSION +#if PROTOBUF_VERSION != 4026000 +#error "Protobuf C++ gencode is built with an incompatible version of" +#error "Protobuf C++ headers/runtime. See" +#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp" +#endif #include "google/protobuf/port_undef.inc" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/arena.h" @@ -104,21 +98,18 @@ inline bool JavaFeatures_Utf8Validation_Parse(absl::string_view name, JavaFeatur // ------------------------------------------------------------------- -class PROTOC_EXPORT JavaFeatures final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:pb.JavaFeatures) */ { +class PROTOC_EXPORT JavaFeatures final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:pb.JavaFeatures) */ { public: inline JavaFeatures() : JavaFeatures(nullptr) {} ~JavaFeatures() override; - template - explicit PROTOBUF_CONSTEXPR JavaFeatures(::google::protobuf::internal::ConstantInitialized); - - inline JavaFeatures(const JavaFeatures& from) - : JavaFeatures(nullptr, from) {} - JavaFeatures(JavaFeatures&& from) noexcept - : JavaFeatures() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR JavaFeatures( + ::google::protobuf::internal::ConstantInitialized); + inline JavaFeatures(const JavaFeatures& from) : JavaFeatures(nullptr, from) {} + inline JavaFeatures(JavaFeatures&& from) noexcept + : JavaFeatures(nullptr, std::move(from)) {} inline JavaFeatures& operator=(const JavaFeatures& from) { CopyFrom(from); return *this; @@ -126,9 +117,9 @@ class PROTOC_EXPORT JavaFeatures final : inline JavaFeatures& operator=(JavaFeatures&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -160,22 +151,17 @@ class PROTOC_EXPORT JavaFeatures final : } static inline const JavaFeatures* internal_default_instance() { return reinterpret_cast( - &_JavaFeatures_default_instance_); - } - static constexpr int kIndexInFileMessages = - 0; - - friend void swap(JavaFeatures& a, JavaFeatures& b) { - a.Swap(&b); + &_JavaFeatures_default_instance_); } + static constexpr int kIndexInFileMessages = 0; + friend void swap(JavaFeatures& a, JavaFeatures& b) { a.Swap(&b); } inline void Swap(JavaFeatures* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -190,16 +176,18 @@ class PROTOC_EXPORT JavaFeatures final : // implements Message ---------------------------------------------- JavaFeatures* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const JavaFeatures& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const JavaFeatures& from) { - JavaFeatures::MergeImpl(*this, from); - } + void MergeFrom(const JavaFeatures& from) { JavaFeatures::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -207,30 +195,31 @@ class PROTOC_EXPORT JavaFeatures final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(JavaFeatures* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "pb.JavaFeatures"; - } - protected: + static ::absl::string_view FullMessageName() { return "pb.JavaFeatures"; } + + protected: explicit JavaFeatures(::google::protobuf::Arena* arena); JavaFeatures(::google::protobuf::Arena* arena, const JavaFeatures& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + JavaFeatures(::google::protobuf::Arena* arena, JavaFeatures&& from) noexcept + : JavaFeatures(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- - using Utf8Validation = JavaFeatures_Utf8Validation; static constexpr Utf8Validation UTF8_VALIDATION_UNKNOWN = JavaFeatures_Utf8Validation_UTF8_VALIDATION_UNKNOWN; static constexpr Utf8Validation DEFAULT = JavaFeatures_Utf8Validation_DEFAULT; @@ -253,7 +242,6 @@ class PROTOC_EXPORT JavaFeatures final : } // accessors ------------------------------------------------------- - enum : int { kLegacyClosedEnumFieldNumber = 1, kUtf8ValidationFieldNumber = 2, @@ -283,7 +271,6 @@ class PROTOC_EXPORT JavaFeatures final : // @@protoc_insertion_point(class_scope:pb.JavaFeatures) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 1, 2, 1, @@ -295,14 +282,13 @@ class PROTOC_EXPORT JavaFeatures final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOC_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; bool legacy_closed_enum_; @@ -318,9 +304,10 @@ class PROTOC_EXPORT JavaFeatures final : static const int kJavaFieldNumber = 1001; -PROTOC_EXPORT extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::FeatureSet, - ::google::protobuf::internal::MessageTypeTraits< ::pb::JavaFeatures >, 11, false > - java; +PROTOC_EXPORT extern ::google::protobuf::internal::ExtensionIdentifier< + ::google::protobuf::FeatureSet, ::google::protobuf::internal::MessageTypeTraits< ::pb::JavaFeatures >, 11, + false> + java; // =================================================================== @@ -349,6 +336,7 @@ inline bool JavaFeatures::legacy_closed_enum() const { } inline void JavaFeatures::set_legacy_closed_enum(bool value) { _internal_set_legacy_closed_enum(value); + _impl_._has_bits_[0] |= 0x00000001u; // @@protoc_insertion_point(field_set:pb.JavaFeatures.legacy_closed_enum) } inline bool JavaFeatures::_internal_legacy_closed_enum() const { @@ -357,7 +345,6 @@ inline bool JavaFeatures::_internal_legacy_closed_enum() const { } inline void JavaFeatures::_internal_set_legacy_closed_enum(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000001u; _impl_.legacy_closed_enum_ = value; } @@ -377,6 +364,7 @@ inline ::pb::JavaFeatures_Utf8Validation JavaFeatures::utf8_validation() const { } inline void JavaFeatures::set_utf8_validation(::pb::JavaFeatures_Utf8Validation value) { _internal_set_utf8_validation(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:pb.JavaFeatures.utf8_validation) } inline ::pb::JavaFeatures_Utf8Validation JavaFeatures::_internal_utf8_validation() const { @@ -386,7 +374,6 @@ inline ::pb::JavaFeatures_Utf8Validation JavaFeatures::_internal_utf8_validation inline void JavaFeatures::_internal_set_utf8_validation(::pb::JavaFeatures_Utf8Validation value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::pb::JavaFeatures_Utf8Validation_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.utf8_validation_ = value; } diff --git a/src/google/protobuf/compiler/java/message.cc b/src/google/protobuf/compiler/java/message.cc index d170cfa38f..5f1db0493c 100644 --- a/src/google/protobuf/compiler/java/message.cc +++ b/src/google/protobuf/compiler/java/message.cc @@ -340,6 +340,15 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { printer->Print("private static final long serialVersionUID = 0L;\n"); printer->Indent(); + + if (context_->options().opensource_runtime) { + printer->Print("static {\n"); + printer->Indent(); + PrintGencodeVersionValidator(printer); + printer->Outdent(); + printer->Print("}\n"); + } + // Using builder_type, instead of Builder, prevents the Builder class from // being loaded into PermGen space when the default instance is created. // This optimizes the PermGen space usage for clients that do not modify @@ -1131,7 +1140,7 @@ void ImmutableMessageGenerator::GenerateExtensionRegistrationCode( // =================================================================== void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) { printer->Print( - "$visibility$ static final com.google.protobuf.Parser<$classname$>\n" + "private static final com.google.protobuf.Parser<$classname$>\n" " PARSER = new com.google.protobuf.AbstractParser<$classname$>() {\n" " @java.lang.Override\n" " public $classname$ parsePartialFrom(\n" @@ -1164,9 +1173,6 @@ void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) { " return PARSER;\n" "}\n" "\n", - "visibility", - ExposePublicParser(descriptor_->file()) ? "@java.lang.Deprecated public" - : "private", "classname", descriptor_->name()); } diff --git a/src/google/protobuf/compiler/java/message_field.cc b/src/google/protobuf/compiler/java/message_field.cc index 56c06c0fcd..d5f8987457 100644 --- a/src/google/protobuf/compiler/java/message_field.cc +++ b/src/google/protobuf/compiler/java/message_field.cc @@ -19,7 +19,6 @@ #include "google/protobuf/compiler/java/doc_comment.h" #include "google/protobuf/compiler/java/helpers.h" #include "google/protobuf/compiler/java/name_resolver.h" -#include "google/protobuf/descriptor_legacy.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/wire_format.h" @@ -62,11 +61,7 @@ void SetMessageVariables( : ""}); (*variables)["on_changed"] = "onChanged();"; (*variables)["ver"] = GeneratedCodeVersionSuffix(); - (*variables)["get_parser"] = - ExposePublicParser(descriptor->message_type()->file()) && - context->options().opensource_runtime - ? "PARSER" - : "parser()"; + (*variables)["get_parser"] = "parser()"; if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. @@ -342,7 +337,7 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( " $on_changed$\n" " return get$capitalized_name$FieldBuilder().getBuilder();\n" "}\n"); - printer->Annotate("{", "}", descriptor_); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); // FieldOrBuilder getFieldOrBuilder() WriteFieldDocComment(printer, descriptor_, context_->options()); @@ -411,7 +406,8 @@ void ImmutableMessageFieldGenerator::GenerateKotlinDslMembers( } void ImmutableMessageFieldGenerator::GenerateKotlinOrNull(io::Printer* printer) const { - if (FieldDescriptorLegacy(descriptor_).has_optional_keyword()) { + if (descriptor_->has_presence() && + descriptor_->real_containing_oneof() == nullptr) { printer->Print(variables_, "public val $classname$Kt.Dsl.$name$OrNull: $kt_type$?\n" " get() = $kt_dsl_builder$.$name$OrNull\n"); @@ -692,7 +688,7 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( "${$get$capitalized_name$Builder$}$() {\n" " return get$capitalized_name$FieldBuilder().getBuilder();\n" "}\n"); - printer->Annotate("{", "}", descriptor_); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print( variables_, @@ -730,7 +726,7 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( " $on_changed$\n" " return $name$Builder_;\n" "}\n"); - printer->Annotate("{", "}", descriptor_); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); } void ImmutableMessageOneofFieldGenerator::GenerateBuilderClearCode( @@ -1148,7 +1144,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( " int index) {\n" " return get$capitalized_name$FieldBuilder().getBuilder(index);\n" "}\n"); - printer->Annotate("{", "}", descriptor_); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); // FieldOrBuilder getRepeatedFieldOrBuilder(int index) WriteFieldDocComment(printer, descriptor_, context_->options()); @@ -1222,7 +1218,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( " }\n" " return $name$Builder_;\n" "}\n"); - printer->Annotate("{", "}", descriptor_); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); } void RepeatedImmutableMessageFieldGenerator:: diff --git a/src/google/protobuf/compiler/java/message_field_lite.cc b/src/google/protobuf/compiler/java/message_field_lite.cc index 17a9fa789f..45997ef324 100644 --- a/src/google/protobuf/compiler/java/message_field_lite.cc +++ b/src/google/protobuf/compiler/java/message_field_lite.cc @@ -19,7 +19,6 @@ #include "google/protobuf/compiler/java/doc_comment.h" #include "google/protobuf/compiler/java/helpers.h" #include "google/protobuf/compiler/java/name_resolver.h" -#include "google/protobuf/descriptor_legacy.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/wire_format.h" @@ -309,7 +308,8 @@ void ImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( } void ImmutableMessageFieldLiteGenerator::GenerateKotlinOrNull(io::Printer* printer) const { - if (FieldDescriptorLegacy(descriptor_).has_optional_keyword()) { + if (descriptor_->has_presence() && + descriptor_->real_containing_oneof() == nullptr) { printer->Print(variables_, "public val $classname$Kt.Dsl.$name$OrNull: $kt_type$?\n" " get() = $kt_dsl_builder$.$name$OrNull\n"); diff --git a/src/google/protobuf/compiler/java/message_lite.cc b/src/google/protobuf/compiler/java/message_lite.cc index 587f2ccf91..71b368997d 100644 --- a/src/google/protobuf/compiler/java/message_lite.cc +++ b/src/google/protobuf/compiler/java/message_lite.cc @@ -31,7 +31,6 @@ #include "google/protobuf/compiler/java/message_builder_lite.h" #include "google/protobuf/compiler/java/name_resolver.h" #include "google/protobuf/descriptor.pb.h" -#include "google/protobuf/descriptor_legacy.h" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/wire_format.h" @@ -69,25 +68,13 @@ ImmutableMessageLiteGenerator::~ImmutableMessageLiteGenerator() {} void ImmutableMessageLiteGenerator::GenerateStaticVariables( io::Printer* printer, int* bytecode_estimate) { - // Generate static members for all nested types. - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - // TODO: Reuse MessageGenerator objects? - ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_) - .GenerateStaticVariables(printer, bytecode_estimate); - } + // No-op for lite. } int ImmutableMessageLiteGenerator::GenerateStaticVariableInitializers( io::Printer* printer) { - int bytecode_estimate = 0; - // Generate static member initializers for all nested types. - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - // TODO: Reuse MessageGenerator objects? - bytecode_estimate += - ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_) - .GenerateStaticVariableInitializers(printer); - } - return bytecode_estimate; + // No-op for lite. + return 0; } // =================================================================== @@ -485,18 +472,13 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuildMessageInfo( std::vector chars; int flags = 0; - if (FileDescriptorLegacy(descriptor_->file()).syntax() == - FileDescriptorLegacy::Syntax::SYNTAX_PROTO2) { - if (!context_->options().strip_nonfunctional_codegen) { - flags |= 0x1; - } - } if (descriptor_->options().message_set_wire_format()) { flags |= 0x2; } - if (FileDescriptorLegacy(descriptor_->file()).syntax() == - FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS) { - if (!context_->options().strip_nonfunctional_codegen) { + if (!context_->options().strip_nonfunctional_codegen) { + if (descriptor_->file()->edition() == Edition::EDITION_PROTO2) { + flags |= 0x1; + } else if (descriptor_->file()->edition() >= Edition::EDITION_2023) { flags |= 0x4; } } diff --git a/src/google/protobuf/compiler/java/shared_code_generator.cc b/src/google/protobuf/compiler/java/shared_code_generator.cc index 3def00c69b..b73c37ea65 100644 --- a/src/google/protobuf/compiler/java/shared_code_generator.cc +++ b/src/google/protobuf/compiler/java/shared_code_generator.cc @@ -83,6 +83,9 @@ void SharedCodeGenerator::Generate( printer->Indent(); printer->Indent(); GenerateDescriptors(printer.get()); + if (options_.opensource_runtime) { + PrintGencodeVersionValidator(printer.get()); + } printer->Outdent(); printer->Outdent(); printer->Print( diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc index d7057a1e67..0cf407de90 100644 --- a/src/google/protobuf/compiler/mock_code_generator.cc +++ b/src/google/protobuf/compiler/mock_code_generator.cc @@ -34,7 +34,6 @@ #include "absl/strings/substitute.h" #include "google/protobuf/compiler/plugin.pb.h" #include "google/protobuf/descriptor.h" -#include "google/protobuf/descriptor_legacy.h" #include "google/protobuf/descriptor_visitor.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/io/zero_copy_stream.h" @@ -80,6 +79,10 @@ MockCodeGenerator::MockCodeGenerator(absl::string_view name) : name_(name) { feature_extensions_ = {nullptr}; } else if (key == "no_feature_defaults") { feature_extensions_ = {}; + } else if (key == "high_maximum") { + maximum_edition_ = Edition::EDITION_99997_TEST_ONLY; + } else if (key == "low_minimum") { + maximum_edition_ = Edition::EDITION_1_TEST_ONLY; } } @@ -203,8 +206,16 @@ bool MockCodeGenerator::Generate(const FileDescriptor* file, const std::string& parameter, GeneratorContext* context, std::string* error) const { - if (FileDescriptorLegacy(file).syntax() == - FileDescriptorLegacy::SYNTAX_EDITIONS && + // Override minimum/maximum after generating the pool to simulate a plugin + // that "works" but doesn't advertise support of the current edition. + absl::string_view test_case = getenv("TEST_CASE"); + if (test_case == "high_minimum") { + minimum_edition_ = Edition::EDITION_99997_TEST_ONLY; + } else if (test_case == "low_maximum") { + maximum_edition_ = Edition::EDITION_PROTO2; + } + + if (file->edition() >= Edition::EDITION_2023 && (suppressed_features_ & CodeGenerator::FEATURE_SUPPORTS_EDITIONS) == 0) { internal::VisitDescriptors(*file, [&](const auto& descriptor) { const FeatureSet& features = GetResolvedSourceFeatures(descriptor); diff --git a/src/google/protobuf/compiler/mock_code_generator.h b/src/google/protobuf/compiler/mock_code_generator.h index 594e16b2b8..8091f38e4a 100644 --- a/src/google/protobuf/compiler/mock_code_generator.h +++ b/src/google/protobuf/compiler/mock_code_generator.h @@ -119,8 +119,8 @@ class MockCodeGenerator : public CodeGenerator { private: std::string name_; uint64_t suppressed_features_ = 0; - Edition minimum_edition_ = PROTOBUF_MINIMUM_EDITION; - Edition maximum_edition_ = PROTOBUF_MAXIMUM_EDITION; + mutable Edition minimum_edition_ = PROTOBUF_MINIMUM_EDITION; + mutable Edition maximum_edition_ = PROTOBUF_MAXIMUM_EDITION; std::vector feature_extensions_ = { GetExtensionReflection(pb::test)}; diff --git a/src/google/protobuf/compiler/objectivec/BUILD.bazel b/src/google/protobuf/compiler/objectivec/BUILD.bazel index a3a6fcfec0..b60a59d3a6 100644 --- a/src/google/protobuf/compiler/objectivec/BUILD.bazel +++ b/src/google/protobuf/compiler/objectivec/BUILD.bazel @@ -95,7 +95,6 @@ cc_library( deps = [ ":line_consumer", ":names", - "//src/google/protobuf:descriptor_legacy", "//src/google/protobuf:protobuf_nowkt", "//src/google/protobuf/compiler:code_generator", "@com_google_absl//absl/container:btree", diff --git a/src/google/protobuf/compiler/objectivec/file.cc b/src/google/protobuf/compiler/objectivec/file.cc index 857dfd73ee..eccec502a7 100644 --- a/src/google/protobuf/compiler/objectivec/file.cc +++ b/src/google/protobuf/compiler/objectivec/file.cc @@ -22,6 +22,8 @@ #include "absl/log/absl_check.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_join.h" +#include "absl/strings/string_view.h" +#include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/compiler/objectivec/enum.h" #include "google/protobuf/compiler/objectivec/extension.h" #include "google/protobuf/compiler/objectivec/helpers.h" @@ -31,7 +33,6 @@ #include "google/protobuf/compiler/objectivec/options.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" -#include "google/protobuf/descriptor_legacy.h" #include "google/protobuf/io/printer.h" namespace google { @@ -140,6 +141,27 @@ void MakeDescriptors( } } +void EmitLinkWKTs(absl::string_view name, io::Printer* p) { + absl::string_view::size_type last_slash = name.rfind('/'); + std::string basename; + if (last_slash == absl::string_view::npos) { + basename = std::string(name); + } else { + basename = std::string(name.substr(last_slash + 1)); + } + + p->Emit({{"basename", StripProto(basename)}}, + R"objc( + // This is to help make sure that the GPBWellKnownTypes.* categories get linked and + // developers do not have to use the `-ObjC` linker flag. More information + // here: https://medium.com/ios-os-x-development/categories-in-static-libraries-78e41f8ddb96 + __attribute__((used)) static NSString* $basename$_importCategories () { + return GPBWellKnownTypesErrorDomain; + } + )objc"); + p->Emit("\n"); +} + void EmitSourceFwdDecls(const absl::btree_set& fwd_decls, io::Printer* p) { if (fwd_decls.empty()) { @@ -386,6 +408,10 @@ void FileGenerator::GenerateSource(io::Printer* p) const { EmitRootImplementation(p, deps_with_extensions); EmitFileDescription(p); + if (is_bundled_proto_ && HasWKTWithObjCCategory(file_)) { + EmitLinkWKTs(file_->name(), p); + } + for (const auto& generator : enum_generators_) { generator->GenerateSource(p); } @@ -396,6 +422,8 @@ void FileGenerator::GenerateSource(io::Printer* p) const { } void FileGenerator::GenerateGlobalSource(io::Printer* p) const { + ABSL_CHECK(!is_bundled_proto_) + << "Bundled protos aren't expected to use multi source generation."; std::vector deps_with_extensions = common_state_->CollectMinimalFileDepsContainingExtensions(file_); GeneratedFileOptions file_options; @@ -417,6 +445,8 @@ void FileGenerator::GenerateGlobalSource(io::Printer* p) const { } void FileGenerator::GenerateSourceForEnums(io::Printer* p) const { + ABSL_CHECK(!is_bundled_proto_) + << "Bundled protos aren't expected to use multi source generation."; // Enum implementation uses atomic in the generated code. GeneratedFileOptions file_options; file_options.extra_system_headers.push_back("stdatomic.h"); @@ -429,6 +459,8 @@ void FileGenerator::GenerateSourceForEnums(io::Printer* p) const { } void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* p) const { + ABSL_CHECK(!is_bundled_proto_) + << "Bundled protos aren't expected to use multi source generation."; const auto& generator = message_generators_[idx]; absl::btree_set fwd_decls; @@ -486,6 +518,9 @@ void FileGenerator::GenerateFile(io::Printer* p, GeneratedFileType file_type, break; case GeneratedFileType::kSource: import_writer.AddRuntimeImport("GPBProtocolBuffers_RuntimeSupport.h"); + if (is_bundled_proto_ && HasWKTWithObjCCategory(file_)) { + import_writer.AddRuntimeImport("GPBWellKnownTypes.h"); + } import_writer.AddFile(file_, header_extension); if (HeadersUseForwardDeclarations()) { if (generation_options_.generate_minimal_imports) { @@ -742,17 +777,17 @@ void FileGenerator::EmitFileDescription(io::Printer* p) const { // mode. syntax = "GPBFileSyntaxUnknown"; } else { - switch (FileDescriptorLegacy(file_).syntax()) { - case FileDescriptorLegacy::Syntax::SYNTAX_UNKNOWN: + switch (file_->edition()) { + case Edition::EDITION_UNKNOWN: syntax = "GPBFileSyntaxUnknown"; break; - case FileDescriptorLegacy::Syntax::SYNTAX_PROTO2: + case Edition::EDITION_PROTO2: syntax = "GPBFileSyntaxProto2"; break; - case FileDescriptorLegacy::Syntax::SYNTAX_PROTO3: + case Edition::EDITION_PROTO3: syntax = "GPBFileSyntaxProto3"; break; - case FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS: + default: syntax = "GPBFileSyntaxProtoEditions"; break; } diff --git a/src/google/protobuf/compiler/objectivec/helpers.cc b/src/google/protobuf/compiler/objectivec/helpers.cc index 0ecb564e90..b1d41803ec 100644 --- a/src/google/protobuf/compiler/objectivec/helpers.cc +++ b/src/google/protobuf/compiler/objectivec/helpers.cc @@ -13,6 +13,7 @@ #include #include +#include "absl/log/absl_check.h" #include "absl/log/absl_log.h" #include "absl/strings/ascii.h" #include "absl/strings/escaping.h" @@ -393,6 +394,33 @@ void EmitCommentsString(io::Printer* printer, const SourceLocation& location, )"); } +bool HasWKTWithObjCCategory(const FileDescriptor* file) { + // We don't check the name prefix or proto package because some files + // (descriptor.proto), aren't shipped generated by the library, so this + // seems to be the safest way to only catch the ones shipped. + const std::string name = file->name(); + if (name == "google/protobuf/any.proto" || + name == "google/protobuf/duration.proto" || + name == "google/protobuf/timestamp.proto") { + ABSL_DCHECK(IsProtobufLibraryBundledProtoFile(file)); + return true; + } + return false; +} + +bool IsWKTWithObjCCategory(const Descriptor* descriptor) { + if (!HasWKTWithObjCCategory(descriptor->file())) { + return false; + } + const std::string full_name = descriptor->full_name(); + if (full_name == "google.protobuf.Any" || + full_name == "google.protobuf.Duration" || + full_name == "google.protobuf.Timestamp") { + return true; + } + return false; +} + } // namespace objectivec } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/objectivec/helpers.h b/src/google/protobuf/compiler/objectivec/helpers.h index 086b71faaf..7b6c2b786d 100644 --- a/src/google/protobuf/compiler/objectivec/helpers.h +++ b/src/google/protobuf/compiler/objectivec/helpers.h @@ -148,6 +148,11 @@ std::string GetOptionalDeprecatedAttribute( } } +// Helpers to identify the WellKnownType files/messages that get an Objective-C +// category within the runtime to add helpers. +bool HasWKTWithObjCCategory(const FileDescriptor* file); +bool IsWKTWithObjCCategory(const Descriptor* descriptor); + } // namespace objectivec } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/objectivec/message.cc b/src/google/protobuf/compiler/objectivec/message.cc index 0030cda550..55fd4d3f2d 100644 --- a/src/google/protobuf/compiler/objectivec/message.cc +++ b/src/google/protobuf/compiler/objectivec/message.cc @@ -336,6 +336,17 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) const { } field_generators_.get(field).GeneratePropertyDeclaration(printer); } + }}, + {"wkt_extra", + [&] { + if (!IsWKTWithObjCCategory(descriptor_)) { + return; + } + printer->Emit(R"objc( + // NOTE: There are some Objective-C specific methods/properties in + // GPBWellKnownTypes.h that will likey be useful. + )objc"); + printer->Emit("\n"); }}}, R"objc( #pragma mark - $classname$ @@ -347,6 +358,7 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) const { GPB_FINAL @interface $classname$ : GPBMessage $message_properties$ + $wkt_extra$ @end )objc"); printer->Emit("\n"); diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc index a402701268..ae6be8ff30 100644 --- a/src/google/protobuf/compiler/parser.cc +++ b/src/google/protobuf/compiler/parser.cc @@ -201,7 +201,7 @@ bool Parser::TryConsume(absl::string_view text) { } } -bool Parser::Consume(absl::string_view text, absl::string_view error) { +bool Parser::Consume(absl::string_view text, ErrorMaker error) { if (TryConsume(text)) { return true; } else { @@ -211,10 +211,11 @@ bool Parser::Consume(absl::string_view text, absl::string_view error) { } bool Parser::Consume(absl::string_view text) { - return Consume(text, absl::StrCat("Expected \"", text, "\".")); + return Consume(text, + [&] { return absl::StrCat("Expected \"", text, "\"."); }); } -bool Parser::ConsumeIdentifier(std::string* output, absl::string_view error) { +bool Parser::ConsumeIdentifier(std::string* output, ErrorMaker error) { if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { *output = input_->current().text; input_->Next(); @@ -225,7 +226,7 @@ bool Parser::ConsumeIdentifier(std::string* output, absl::string_view error) { } } -bool Parser::ConsumeInteger(int* output, absl::string_view error) { +bool Parser::ConsumeInteger(int* output, ErrorMaker error) { if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { uint64_t value = 0; if (!io::Tokenizer::ParseInteger(input_->current().text, @@ -243,7 +244,7 @@ bool Parser::ConsumeInteger(int* output, absl::string_view error) { } } -bool Parser::ConsumeSignedInteger(int* output, absl::string_view error) { +bool Parser::ConsumeSignedInteger(int* output, ErrorMaker error) { bool is_negative = false; uint64_t max_value = std::numeric_limits::max(); if (TryConsume("-")) { @@ -258,7 +259,7 @@ bool Parser::ConsumeSignedInteger(int* output, absl::string_view error) { } bool Parser::ConsumeInteger64(uint64_t max_value, uint64_t* output, - absl::string_view error) { + ErrorMaker error) { if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { if (!io::Tokenizer::ParseInteger(input_->current().text, max_value, output)) { @@ -283,7 +284,7 @@ bool Parser::TryConsumeInteger64(uint64_t max_value, uint64_t* output) { return false; } -bool Parser::ConsumeNumber(double* output, absl::string_view error) { +bool Parser::ConsumeNumber(double* output, ErrorMaker error) { if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) { *output = io::Tokenizer::ParseFloat(input_->current().text); input_->Next(); @@ -320,7 +321,7 @@ bool Parser::ConsumeNumber(double* output, absl::string_view error) { } } -bool Parser::ConsumeString(std::string* output, absl::string_view error) { +bool Parser::ConsumeString(std::string* output, ErrorMaker error) { if (LookingAtType(io::Tokenizer::TYPE_STRING)) { io::Tokenizer::ParseString(input_->current().text, output); input_->Next(); @@ -372,32 +373,34 @@ bool Parser::ConsumeEndOfDeclaration(absl::string_view text, if (TryConsumeEndOfDeclaration(text, location)) { return true; } else { - RecordError(absl::StrCat("Expected \"", text, "\".")); + RecordError([&] { return absl::StrCat("Expected \"", text, "\"."); }); return false; } } // ------------------------------------------------------------------- -void Parser::RecordError(int line, int column, absl::string_view error) { +void Parser::RecordError(int line, int column, ErrorMaker error) { if (error_collector_ != nullptr) { - error_collector_->RecordError(line, column, error); + error_collector_->RecordError(line, column, error.get()); } had_errors_ = true; } -void Parser::RecordError(absl::string_view error) { +void Parser::RecordError(ErrorMaker error) { RecordError(input_->current().line, input_->current().column, error); } -void Parser::RecordWarning(int line, int column, absl::string_view warning) { +void Parser::RecordWarning(int line, int column, ErrorMaker error) { if (error_collector_ != nullptr) { - error_collector_->RecordWarning(line, column, warning); + error_collector_->RecordWarning(line, column, error.get()); } } -void Parser::RecordWarning(absl::string_view warning) { - RecordWarning(input_->current().line, input_->current().column, warning); +// Invokes error_collector_->RecordWarning() with the line and column number +// of the current token. +void Parser::RecordWarning(ErrorMaker error) { + RecordWarning(input_->current().line, input_->current().column, error); } // ------------------------------------------------------------------- @@ -590,12 +593,13 @@ bool Parser::ValidateEnum(const EnumDescriptorProto* proto) { } if (has_allow_alias && !allow_alias) { - std::string error = absl::StrCat( - "\"", proto->name(), - "\" declares 'option allow_alias = false;' which has no effect. " - "Please remove the declaration."); // This needlessly clutters declarations with nops. - RecordError(error); + RecordError([=] { + return absl::StrCat( + "\"", proto->name(), + "\" declares 'option allow_alias = false;' which has no effect. " + "Please remove the declaration."); + }); return false; } @@ -611,14 +615,15 @@ bool Parser::ValidateEnum(const EnumDescriptorProto* proto) { } } if (allow_alias && !has_duplicates) { - std::string error = absl::StrCat( - "\"", proto->name(), - "\" declares support for enum aliases but no enum values share field " - "numbers. Please remove the unnecessary 'option allow_alias = true;' " - "declaration."); // Generate an error if an enum declares support for duplicate enum values // and does not use it protect future authors. - RecordError(error); + RecordError([=] { + return absl::StrCat( + "\"", proto->name(), + "\" declares support for enum aliases but no enum values share field " + "numbers. Please remove the unnecessary 'option allow_alias = true;' " + "declaration."); + }); return false; } @@ -627,9 +632,13 @@ bool Parser::ValidateEnum(const EnumDescriptorProto* proto) { if (!allow_alias) { for (const auto& enum_value : proto->value()) { if (!IsUpperUnderscore(enum_value.name())) { - RecordWarning(absl::StrCat( - "Enum constant should be in UPPER_CASE. Found: ", enum_value.name(), - ". See https://developers.google.com/protocol-buffers/docs/style")); + RecordWarning([&] { + return absl::StrCat( + "Enum constant should be in UPPER_CASE. Found: ", + enum_value.name(), + ". See " + "https://developers.google.com/protocol-buffers/docs/style"); + }); } } } @@ -731,9 +740,12 @@ bool Parser::ParseSyntaxIdentifier(const FileDescriptorProto* file, if (has_edition) { if (!Edition_Parse(absl::StrCat("EDITION_", syntax), &edition_) || - edition_ < Edition::EDITION_2023) { - RecordError(syntax_token.line, syntax_token.column, - absl::StrCat("Unknown edition \"", syntax, "\".")); + edition_ == Edition::EDITION_PROTO2 || + edition_ == Edition::EDITION_PROTO3 || + edition_ == Edition::EDITION_UNKNOWN) { + RecordError(syntax_token.line, syntax_token.column, [&] { + return absl::StrCat("Unknown edition \"", syntax, "\"."); + }); return false; } syntax_identifier_ = "editions"; @@ -743,10 +755,11 @@ bool Parser::ParseSyntaxIdentifier(const FileDescriptorProto* file, syntax_identifier_ = syntax; if (syntax != "proto2" && syntax != "proto3" && !stop_after_syntax_identifier_) { - RecordError(syntax_token.line, syntax_token.column, - absl::StrCat("Unrecognized syntax identifier \"", syntax, - "\". This parser " - "only recognizes \"proto2\" and \"proto3\".")); + RecordError(syntax_token.line, syntax_token.column, [&] { + return absl::StrCat("Unrecognized syntax identifier \"", syntax, + "\". This parser " + "only recognizes \"proto2\" and \"proto3\"."); + }); return false; } @@ -847,9 +860,12 @@ bool Parser::ParseMessageDefinition( DescriptorPool::ErrorCollector::NAME); DO(ConsumeIdentifier(message->mutable_name(), "Expected message name.")); if (!IsUpperCamelCase(message->name())) { - RecordWarning(absl::StrCat( - "Message name should be in UpperCamelCase. Found: ", message->name(), - ". See https://developers.google.com/protocol-buffers/docs/style")); + RecordWarning([=] { + return absl::StrCat( + "Message name should be in UpperCamelCase. Found: ", + message->name(), + ". See https://developers.google.com/protocol-buffers/docs/style"); + }); } } DO(ParseMessageBlock(message, message_location, containing_file)); @@ -1080,15 +1096,19 @@ bool Parser::ParseMessageFieldNoLabel( DO(ConsumeIdentifier(field->mutable_name(), "Expected field name.")); if (!IsLowerUnderscore(field->name())) { - RecordWarning(absl::StrCat( - "Field name should be lowercase. Found: ", field->name(), - ". See: https://developers.google.com/protocol-buffers/docs/style")); + RecordWarning([=] { + return absl::StrCat( + "Field name should be lowercase. Found: ", field->name(), + ". See: https://developers.google.com/protocol-buffers/docs/style"); + }); } if (IsNumberFollowUnderscore(field->name())) { - RecordWarning(absl::StrCat( - "Number should not come right after an underscore. Found: ", - field->name(), - ". See: https://developers.google.com/protocol-buffers/docs/style")); + RecordWarning([=] { + return absl::StrCat( + "Number should not come right after an underscore. Found: ", + field->name(), + ". See: https://developers.google.com/protocol-buffers/docs/style"); + }); } } DO(Consume("=", "Missing field number.")); @@ -1819,18 +1839,17 @@ bool Parser::ParseReserved(DescriptorProto* message, } } -bool Parser::ParseReservedName(std::string* name, - absl::string_view error_message) { +bool Parser::ParseReservedName(std::string* name, ErrorMaker error_message) { // Capture the position of the token, in case we have to report an // error after it is consumed. int line = input_->current().line; int col = input_->current().column; DO(ConsumeString(name, error_message)); if (!io::Tokenizer::IsIdentifier(*name)) { - RecordWarning( - line, col, - absl::StrFormat("Reserved name \"%s\" is not a valid identifier.", - *name)); + RecordWarning(line, col, [=] { + return absl::StrFormat("Reserved name \"%s\" is not a valid identifier.", + *name); + }); } return true; } @@ -1847,7 +1866,7 @@ bool Parser::ParseReservedNames(DescriptorProto* message, } bool Parser::ParseReservedIdentifier(std::string* name, - absl::string_view error_message) { + ErrorMaker error_message) { DO(ConsumeIdentifier(name, error_message)); return true; } diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h index f3e6460a7e..7ed020f7dc 100644 --- a/src/google/protobuf/compiler/parser.h +++ b/src/google/protobuf/compiler/parser.h @@ -16,6 +16,7 @@ #include #include +#include #include #include "absl/container/flat_hash_map.h" @@ -139,33 +140,65 @@ class PROTOBUF_EXPORT Parser { // true. Otherwise, return false without logging an error. bool TryConsume(absl::string_view text); + // In the following functions the error is passed as a lazily evaluated + // callable to reduce stack usage and delay the actual execution of the error + // statement. + // Super simple type erasure interface. Similar to absl::FunctionRef but takes + // the callable by value. Optimized for lambdas with at most a single pointer + // as payload. + class ErrorMaker { + using StorageT = void*; + + public: + template ()())>::value>> + ErrorMaker(F f) { + static_assert(sizeof(F) <= sizeof(StorageT), ""); + static_assert(alignof(F) <= alignof(StorageT), ""); + static_assert(std::is_trivially_destructible::value, ""); + ::new (static_cast(storage_)) F(f); + func_ = [](const void* p) { return (*reinterpret_cast(p))(); }; + } + // This overload helps callers that just want to pass a literal string. + ErrorMaker(const char* error) : error_(error), func_(nullptr) {} + + std::string get() const { return func_ ? func_(storage_) : error_; } + + private: + union { + alignas(StorageT) char storage_[sizeof(StorageT)]; + const char* error_; + }; + std::string (*func_)(const void*); + }; + // These attempt to read some kind of token from the input. If successful, // they return true. Otherwise they return false and add the given error // to the error list. // Consume a token with the exact text given. - bool Consume(absl::string_view text, absl::string_view error); + bool Consume(absl::string_view text, ErrorMaker error); // Same as above, but automatically generates the error "Expected \"text\".", // where "text" is the expected token text. bool Consume(absl::string_view text); // Consume a token of type IDENTIFIER and store its text in "output". - bool ConsumeIdentifier(std::string* output, absl::string_view error); + bool ConsumeIdentifier(std::string* output, ErrorMaker error); // Consume an integer and store its value in "output". - bool ConsumeInteger(int* output, absl::string_view error); + bool ConsumeInteger(int* output, ErrorMaker error); // Consume a signed integer and store its value in "output". - bool ConsumeSignedInteger(int* output, absl::string_view error); + bool ConsumeSignedInteger(int* output, ErrorMaker error); // Consume a 64-bit integer and store its value in "output". If the value // is greater than max_value, an error will be reported. - bool ConsumeInteger64(uint64_t max_value, uint64_t* output, - absl::string_view error); + bool ConsumeInteger64(uint64_t max_value, uint64_t* output, ErrorMaker error); // Try to consume a 64-bit integer and store its value in "output". No // error is reported on failure, allowing caller to consume token another way. bool TryConsumeInteger64(uint64_t max_value, uint64_t* output); // Consume a number and store its value in "output". This will accept // tokens of either INTEGER or FLOAT type. - bool ConsumeNumber(double* output, absl::string_view error); + bool ConsumeNumber(double* output, ErrorMaker error); // Consume a string literal and store its (unescaped) value in "output". - bool ConsumeString(std::string* output, absl::string_view error); + bool ConsumeString(std::string* output, ErrorMaker error); // Consume a token representing the end of the statement. Comments between // this token and the next will be harvested for documentation. The given @@ -188,18 +221,18 @@ class PROTOBUF_EXPORT Parser { // Error logging helpers // Invokes error_collector_->RecordError(), if error_collector_ is not NULL. - void RecordError(int line, int column, absl::string_view error); + PROTOBUF_NOINLINE void RecordError(int line, int column, ErrorMaker error); // Invokes error_collector_->RecordError() with the line and column number // of the current token. - void RecordError(absl::string_view error); + PROTOBUF_NOINLINE void RecordError(ErrorMaker error); // Invokes error_collector_->RecordWarning(), if error_collector_ is not NULL. - void RecordWarning(int line, int column, absl::string_view warning); + PROTOBUF_NOINLINE void RecordWarning(int line, int column, ErrorMaker error); // Invokes error_collector_->RecordWarning() with the line and column number // of the current token. - void RecordWarning(absl::string_view warning); + PROTOBUF_NOINLINE void RecordWarning(ErrorMaker error); // Records a location in the SourceCodeInfo.location table (see // descriptor.proto). We use RAII to ensure that the start and end locations @@ -379,11 +412,10 @@ class PROTOBUF_EXPORT Parser { const LocationRecorder& message_location); bool ParseReservedNames(DescriptorProto* message, const LocationRecorder& parent_location); - bool ParseReservedName(std::string* name, absl::string_view error_message); + bool ParseReservedName(std::string* name, ErrorMaker error_message); bool ParseReservedIdentifiers(DescriptorProto* message, const LocationRecorder& parent_location); - bool ParseReservedIdentifier(std::string* name, - absl::string_view error_message); + bool ParseReservedIdentifier(std::string* name, ErrorMaker error_message); bool ParseReservedNumbers(DescriptorProto* message, const LocationRecorder& parent_location); bool ParseReserved(EnumDescriptorProto* message, diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc index fca35845b5..89e04d98c5 100644 --- a/src/google/protobuf/compiler/parser_unittest.cc +++ b/src/google/protobuf/compiler/parser_unittest.cc @@ -118,6 +118,7 @@ class ParserTest : public testing::Test { // We don't cover SourceCodeInfo in these tests. actual.clear_source_code_info(); + // Parse the ASCII representation in order to canonicalize it. We could // just compare directly to actual.DebugString(), but that would require // that the caller precisely match the formatting that DebugString() diff --git a/src/google/protobuf/compiler/php/BUILD.bazel b/src/google/protobuf/compiler/php/BUILD.bazel index 2a9746d808..5bddf38779 100644 --- a/src/google/protobuf/compiler/php/BUILD.bazel +++ b/src/google/protobuf/compiler/php/BUILD.bazel @@ -32,7 +32,6 @@ cc_library( ], deps = [ ":names", - "//src/google/protobuf:descriptor_legacy", "//src/google/protobuf:protobuf_nowkt", "//src/google/protobuf/compiler:code_generator", "//src/google/protobuf/compiler:retention", @@ -40,6 +39,18 @@ cc_library( ], ) +cc_test( + name = "generator_unittest", + srcs = ["generator_unittest.cc"], + deps = [ + ":php", + "//:protobuf", + "//src/google/protobuf/compiler:command_line_interface_tester", + "@com_google_googletest//:gtest", + "@com_google_googletest//:gtest_main", + ], +) + ################################################################################ # Distribution packaging ################################################################################ diff --git a/src/google/protobuf/compiler/php/generator_unittest.cc b/src/google/protobuf/compiler/php/generator_unittest.cc new file mode 100644 index 0000000000..e53e1d6d94 --- /dev/null +++ b/src/google/protobuf/compiler/php/generator_unittest.cc @@ -0,0 +1,112 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include + +#include "google/protobuf/descriptor.pb.h" +#include +#include "google/protobuf/compiler/command_line_interface_tester.h" +#include "google/protobuf/compiler/php/php_generator.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace php { +namespace { + +class PhpGeneratorTest : public CommandLineInterfaceTester { + protected: + PhpGeneratorTest() { + RegisterGenerator("--php_out", "--php_opt", std::make_unique(), + "PHP test generator"); + + // Generate built-in protos. + CreateTempFile( + "google/protobuf/descriptor.proto", + google::protobuf::DescriptorProto::descriptor()->file()->DebugString()); + } +}; + +TEST_F(PhpGeneratorTest, Basic) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + message Foo { + optional int32 bar = 1; + int32 baz = 2; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --php_out=$tmpdir foo.proto"); + + ExpectNoErrors(); +} + +TEST_F(PhpGeneratorTest, Proto2File) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto2"; + message Foo { + optional int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --php_out=$tmpdir foo.proto"); + + ExpectNoErrors(); +} + +TEST_F(PhpGeneratorTest, RequiredFieldError) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto2"; + message FooBar { + required int32 foo_message = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --php_out=$tmpdir foo.proto"); + + ExpectErrorSubstring( + "Can't generate PHP code for required field FooBar.foo_message"); +} + +TEST_F(PhpGeneratorTest, GroupFieldError) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto2"; + message Foo { + optional group Bar = 1 { + optional int32 baz = 1; + }; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --php_out=$tmpdir foo.proto"); + + ExpectErrorSubstring("Can't generate PHP code for group field Foo.bar"); +} + +TEST_F(PhpGeneratorTest, ClosedEnumError) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto2"; + enum Foo { + BAR = 0; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --php_out=$tmpdir foo.proto"); + + ExpectErrorSubstring("Can't generate PHP code for closed enum Foo"); +} + +} // namespace +} // namespace php +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index 433474c83e..62498abc6f 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -12,7 +12,6 @@ #include #include -#include "google/protobuf/compiler/code_generator.h" #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/log/absl_log.h" @@ -22,10 +21,11 @@ #include "absl/strings/str_replace.h" #include "absl/strings/str_split.h" #include "absl/strings/string_view.h" +#include "google/protobuf/compiler/code_generator.h" +#include "google/protobuf/compiler/php/names.h" #include "google/protobuf/compiler/retention.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" -#include "google/protobuf/descriptor_legacy.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/io/zero_copy_stream.h" @@ -537,8 +537,20 @@ void Outdent(io::Printer* printer) { printer->Outdent(); } -void GenerateField(const FieldDescriptor* field, io::Printer* printer, - const Options& options) { +bool GenerateField(const FieldDescriptor* field, io::Printer* printer, + const Options& options, std::string* error) { + if (field->is_required()) { + *error = absl::StrCat("Can't generate PHP code for required field ", + field->full_name(), ".\n"); + return false; + } + if (field->type() == FieldDescriptor::TYPE_GROUP) { + *error = absl::StrCat("Can't generate PHP code for group field ", + field->full_name(), + ". Use regular message encoding instead.\n"); + return false; + } + if (field->is_repeated()) { GenerateFieldDocComment(printer, field, options, kFieldProperty); printer->Print( @@ -546,7 +558,7 @@ void GenerateField(const FieldDescriptor* field, io::Printer* printer, "name", field->name()); } else if (field->real_containing_oneof()) { // Oneof fields are handled by GenerateOneofField. - return; + return true; } else { std::string initial_value = field->has_presence() ? "null" : DefaultForField(field); @@ -556,6 +568,7 @@ void GenerateField(const FieldDescriptor* field, io::Printer* printer, "name", field->name(), "initial_value", initial_value); } + return true; } void GenerateOneofField(const OneofDescriptor* oneof, io::Printer* printer) { @@ -1270,9 +1283,17 @@ void LegacyReadOnlyGenerateClassFile(const FileDescriptor* file, "fullname", classname); } -void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, +bool GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, const Options& options, - GeneratorContext* generator_context) { + GeneratorContext* generator_context, std::string* error) { + if (en->is_closed()) { + *error = absl::StrCat("Can't generate PHP code for closed enum ", + en->full_name(), + ". Please use either proto3 or editions without " + "`enum_type = CLOSED`.\n"); + return false; + } + std::string filename = GeneratedClassFileName(en, options); std::unique_ptr output( generator_context->Open(filename)); @@ -1403,15 +1424,18 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, "old", en->name()); LegacyReadOnlyGenerateClassFile(file, en, options, generator_context); } + + return true; } -void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, +bool GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, const Options& options, - GeneratorContext* generator_context) { + GeneratorContext* generator_context, + std::string* error) { // Don't generate MapEntry messages -- we use the PHP extension's native // support for map fields instead. if (message->options().map_entry()) { - return; + return true; } std::string filename = GeneratedClassFileName(message, options); @@ -1461,7 +1485,9 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, // Field and oneof definitions. for (int i = 0; i < message->field_count(); i++) { const FieldDescriptor* field = message->field(i); - GenerateField(field, &printer, options); + if (!GenerateField(field, &printer, options, error)) { + return false; + } } for (int i = 0; i < message->real_oneof_decl_count(); i++) { const OneofDescriptor* oneof = message->oneof_decl(i); @@ -1533,12 +1559,18 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, // Nested messages and enums. for (int i = 0; i < message->nested_type_count(); i++) { - GenerateMessageFile(file, message->nested_type(i), options, - generator_context); + if (!GenerateMessageFile(file, message->nested_type(i), options, + generator_context, error)) { + return false; + } } for (int i = 0; i < message->enum_type_count(); i++) { - GenerateEnumFile(file, message->enum_type(i), options, generator_context); + if (!GenerateEnumFile(file, message->enum_type(i), options, + generator_context, error)) { + return false; + } } + return true; } void GenerateServiceFile( @@ -1588,22 +1620,29 @@ void GenerateServiceFile( printer.Print("}\n\n"); } -void GenerateFile(const FileDescriptor* file, const Options& options, - GeneratorContext* generator_context) { +bool GenerateFile(const FileDescriptor* file, const Options& options, + GeneratorContext* generator_context, std::string* error) { GenerateMetadataFile(file, options, generator_context); for (int i = 0; i < file->message_type_count(); i++) { - GenerateMessageFile(file, file->message_type(i), options, - generator_context); + if (!GenerateMessageFile(file, file->message_type(i), options, + generator_context, error)) { + return false; + } } for (int i = 0; i < file->enum_type_count(); i++) { - GenerateEnumFile(file, file->enum_type(i), options, generator_context); + if (!GenerateEnumFile(file, file->enum_type(i), options, generator_context, + error)) { + return false; + } } if (file->options().php_generic_services()) { for (int i = 0; i < file->service_count(); i++) { GenerateServiceFile(file, file->service(i), options, generator_context); } } + + return true; } static std::string EscapePhpdoc(absl::string_view input) { @@ -2283,18 +2322,7 @@ bool Generator::Generate(const FileDescriptor* file, const Options& options, return false; } - if (!options.is_descriptor && - FileDescriptorLegacy(file).syntax() != - FileDescriptorLegacy::Syntax::SYNTAX_PROTO3) { - *error = - "Can only generate PHP code for proto3 .proto files.\n" - "Please add 'syntax = \"proto3\";' to the top of your .proto file.\n"; - return false; - } - - GenerateFile(file, options, generator_context); - - return true; + return GenerateFile(file, options, generator_context, error); } bool Generator::GenerateAll(const std::vector& files, diff --git a/src/google/protobuf/compiler/php/php_generator.h b/src/google/protobuf/compiler/php/php_generator.h index 8a045249db..a270b2004f 100644 --- a/src/google/protobuf/compiler/php/php_generator.h +++ b/src/google/protobuf/compiler/php/php_generator.h @@ -8,12 +8,12 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_PHP_GENERATOR_H__ #define GOOGLE_PROTOBUF_COMPILER_PHP_GENERATOR_H__ +#include +#include + #include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/compiler/php/names.h" #include "google/protobuf/descriptor.h" - -#include - #include "google/protobuf/port_def.inc" namespace google { diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc index 166e1c0851..7c498e2f1e 100644 --- a/src/google/protobuf/compiler/plugin.cc +++ b/src/google/protobuf/compiler/plugin.cc @@ -10,6 +10,7 @@ #include "google/protobuf/compiler/plugin.h" #include +#include #include #ifdef _WIN32 @@ -18,6 +19,8 @@ #include #endif +#include "absl/log/absl_check.h" +#include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/code_generator.h" @@ -102,7 +105,8 @@ bool GenerateCode(const CodeGeneratorRequest& request, defaults.status().message()); return false; } - pool.SetFeatureSetDefaults(*defaults); + absl::Status status = pool.SetFeatureSetDefaults(std::move(defaults).value()); + ABSL_CHECK(status.ok()) << status.message(); for (int i = 0; i < request.proto_file_size(); i++) { const FileDescriptor* file = pool.BuildFile(request.proto_file(i)); @@ -133,6 +137,10 @@ bool GenerateCode(const CodeGeneratorRequest& request, &context, &error); response->set_supported_features(generator.GetSupportedFeatures()); + response->set_minimum_edition( + static_cast(generator.GetMinimumEdition())); + response->set_maximum_edition( + static_cast(generator.GetMaximumEdition())); if (!succeeded && error.empty()) { error = diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index 06e403cc6e..3c1ac59a0d 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -1,5 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/compiler/plugin.proto +// Protobuf C++ Version: 4.26.0-dev #include "google/protobuf/compiler/plugin.pb.h" @@ -83,7 +84,9 @@ inline constexpr CodeGeneratorResponse::Impl_::Impl_( error_( &::google::protobuf::internal::fixed_address_empty_string, ::_pbi::ConstantInitialized()), - supported_features_{::uint64_t{0u}} {} + supported_features_{::uint64_t{0u}}, + minimum_edition_{0}, + maximum_edition_{0} {} template PROTOBUF_CONSTEXPR CodeGeneratorResponse::CodeGeneratorResponse(::_pbi::ConstantInitialized) @@ -193,9 +196,13 @@ const ::uint32_t ~0u, // no sizeof(Split) PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_.error_), PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_.supported_features_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_.minimum_edition_), + PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_.maximum_edition_), PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_.file_), 0, 1, + 2, + 3, ~0u, }; @@ -204,7 +211,7 @@ static const ::_pbi::MigrationSchema {0, 12, -1, sizeof(::google::protobuf::compiler::Version)}, {16, 29, -1, sizeof(::google::protobuf::compiler::CodeGeneratorRequest)}, {34, 46, -1, sizeof(::google::protobuf::compiler::CodeGeneratorResponse_File)}, - {50, 61, -1, sizeof(::google::protobuf::compiler::CodeGeneratorResponse)}, + {50, 63, -1, sizeof(::google::protobuf::compiler::CodeGeneratorResponse)}, }; static const ::_pb::Message* const file_default_instances[] = { @@ -225,19 +232,20 @@ const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2epro "FileDescriptorProto\022E\n\027source_file_descr" "iptors\030\021 \003(\0132$.google.protobuf.FileDescr" "iptorProto\022;\n\020compiler_version\030\003 \001(\0132!.g" - "oogle.protobuf.compiler.Version\"\340\002\n\025Code" + "oogle.protobuf.compiler.Version\"\222\003\n\025Code" "GeneratorResponse\022\r\n\005error\030\001 \001(\t\022\032\n\022supp" - "orted_features\030\002 \001(\004\022B\n\004file\030\017 \003(\01324.goo" - "gle.protobuf.compiler.CodeGeneratorRespo" - "nse.File\032\177\n\004File\022\014\n\004name\030\001 \001(\t\022\027\n\017insert" - "ion_point\030\002 \001(\t\022\017\n\007content\030\017 \001(\t\022\?\n\023gene" - "rated_code_info\030\020 \001(\0132\".google.protobuf." - "GeneratedCodeInfo\"W\n\007Feature\022\020\n\014FEATURE_" - "NONE\020\000\022\033\n\027FEATURE_PROTO3_OPTIONAL\020\001\022\035\n\031F" - "EATURE_SUPPORTS_EDITIONS\020\002Br\n\034com.google" - ".protobuf.compilerB\014PluginProtosZ)google" - ".golang.org/protobuf/types/pluginpb\252\002\030Go" - "ogle.Protobuf.Compiler" + "orted_features\030\002 \001(\004\022\027\n\017minimum_edition\030" + "\003 \001(\005\022\027\n\017maximum_edition\030\004 \001(\005\022B\n\004file\030\017" + " \003(\01324.google.protobuf.compiler.CodeGene" + "ratorResponse.File\032\177\n\004File\022\014\n\004name\030\001 \001(\t" + "\022\027\n\017insertion_point\030\002 \001(\t\022\017\n\007content\030\017 \001" + "(\t\022\?\n\023generated_code_info\030\020 \001(\0132\".google" + ".protobuf.GeneratedCodeInfo\"W\n\007Feature\022\020" + "\n\014FEATURE_NONE\020\000\022\033\n\027FEATURE_PROTO3_OPTIO" + "NAL\020\001\022\035\n\031FEATURE_SUPPORTS_EDITIONS\020\002Br\n\034" + "com.google.protobuf.compilerB\014PluginProt" + "osZ)google.golang.org/protobuf/types/plu" + "ginpb\252\002\030Google.Protobuf.Compiler" }; static const ::_pbi::DescriptorTable* const descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps[1] = { @@ -247,7 +255,7 @@ static ::absl::once_flag descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = { false, false, - 902, + 952, descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto, "google/protobuf/compiler/plugin.proto", &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, @@ -276,9 +284,6 @@ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fpl PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto; } -// Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 -static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fcompiler_2fplugin_2eproto(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto); namespace google { namespace protobuf { namespace compiler { @@ -310,18 +315,6 @@ class Version::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(Version, _impl_._has_bits_); - static void set_has_major(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_minor(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_patch(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_suffix(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } }; Version::Version(::google::protobuf::Arena* arena) @@ -384,12 +377,13 @@ inline void Version::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* Version::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { Version::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(Version, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void Version::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.Version) @@ -432,6 +426,9 @@ const ::_pbi::TcParseTable<2, 4, 0, 47, 2> Version::_table_ = { offsetof(decltype(_table_), field_names), // no aux_entries &_Version_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::compiler::Version>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // optional string suffix = 4; {::_pbi::TcParser::FastSS1, @@ -554,7 +551,7 @@ const ::_pbi::TcParseTable<2, 4, 0, 47, 2> Version::_table_ = { } -void Version::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void Version::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.Version) @@ -576,8 +573,8 @@ void Version::MergeImpl(::google::protobuf::Message& to_msg, const ::google::pro if (cached_has_bits & 0x00000008u) { _this->_impl_.patch_ = from._impl_.patch_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -592,9 +589,6 @@ PROTOBUF_NOINLINE bool Version::IsInitialized() const { return true; } -::_pbi::CachedSize* Version::AccessCachedSize() const { - return &_impl_._cached_size_; -} void Version::InternalSwap(Version* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -611,9 +605,9 @@ void Version::InternalSwap(Version* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata Version::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, - file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[0]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, + file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[0]); } // =================================================================== @@ -622,18 +616,8 @@ class CodeGeneratorRequest::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_._has_bits_); - static void set_has_parameter(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static const ::google::protobuf::compiler::Version& compiler_version(const CodeGeneratorRequest* msg); - static void set_has_compiler_version(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } }; -const ::google::protobuf::compiler::Version& CodeGeneratorRequest::_Internal::compiler_version(const CodeGeneratorRequest* msg) { - return *msg->_impl_.compiler_version_; -} void CodeGeneratorRequest::clear_proto_file() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); _impl_.proto_file_.Clear(); @@ -667,9 +651,9 @@ CodeGeneratorRequest::CodeGeneratorRequest( from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.compiler_version_ = (cached_has_bits & 0x00000002u) - ? CreateMaybeMessage<::google::protobuf::compiler::Version>(arena, *from._impl_.compiler_version_) - : nullptr; + _impl_.compiler_version_ = (cached_has_bits & 0x00000002u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::compiler::Version>( + arena, *from._impl_.compiler_version_) + : nullptr; // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorRequest) } @@ -701,12 +685,13 @@ inline void CodeGeneratorRequest::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* CodeGeneratorRequest::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { CodeGeneratorRequest::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void CodeGeneratorRequest::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorRequest) @@ -753,6 +738,9 @@ const ::_pbi::TcParseTable<3, 5, 3, 79, 2> CodeGeneratorRequest::_table_ = { offsetof(decltype(_table_), aux_entries), &_CodeGeneratorRequest_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::compiler::CodeGeneratorRequest>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // repeated string file_to_generate = 1; @@ -827,8 +815,7 @@ const ::_pbi::TcParseTable<3, 5, 3, 79, 2> CodeGeneratorRequest::_table_ = { // optional .google.protobuf.compiler.Version compiler_version = 3; if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 3, _Internal::compiler_version(this), - _Internal::compiler_version(this).GetCachedSize(), target, stream); + 3, *_impl_.compiler_version_, _impl_.compiler_version_->GetCachedSize(), target, stream); } // repeated .google.protobuf.FileDescriptorProto proto_file = 15; @@ -901,9 +888,10 @@ const ::_pbi::TcParseTable<3, 5, 3, 79, 2> CodeGeneratorRequest::_table_ = { } -void CodeGeneratorRequest::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void CodeGeneratorRequest::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -920,10 +908,16 @@ void CodeGeneratorRequest::MergeImpl(::google::protobuf::Message& to_msg, const _this->_internal_set_parameter(from._internal_parameter()); } if (cached_has_bits & 0x00000002u) { - _this->_internal_mutable_compiler_version()->::google::protobuf::compiler::Version::MergeFrom( - from._internal_compiler_version()); + ABSL_DCHECK(from._impl_.compiler_version_ != nullptr); + if (_this->_impl_.compiler_version_ == nullptr) { + _this->_impl_.compiler_version_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::compiler::Version>(arena, *from._impl_.compiler_version_); + } else { + _this->_impl_.compiler_version_->MergeFrom(*from._impl_.compiler_version_); + } } } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -942,9 +936,6 @@ PROTOBUF_NOINLINE bool CodeGeneratorRequest::IsInitialized() const { return true; } -::_pbi::CachedSize* CodeGeneratorRequest::AccessCachedSize() const { - return &_impl_._cached_size_; -} void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -959,9 +950,9 @@ void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* PROTOBUF_RESTRICT } ::google::protobuf::Metadata CodeGeneratorRequest::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, - file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, + file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1]); } // =================================================================== @@ -970,24 +961,8 @@ class CodeGeneratorResponse_File::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_._has_bits_); - static void set_has_name(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_insertion_point(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_content(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static const ::google::protobuf::GeneratedCodeInfo& generated_code_info(const CodeGeneratorResponse_File* msg); - static void set_has_generated_code_info(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } }; -const ::google::protobuf::GeneratedCodeInfo& CodeGeneratorResponse_File::_Internal::generated_code_info(const CodeGeneratorResponse_File* msg) { - return *msg->_impl_.generated_code_info_; -} void CodeGeneratorResponse_File::clear_generated_code_info() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (_impl_.generated_code_info_ != nullptr) _impl_.generated_code_info_->Clear(); @@ -1017,9 +992,9 @@ CodeGeneratorResponse_File::CodeGeneratorResponse_File( from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.generated_code_info_ = (cached_has_bits & 0x00000008u) - ? CreateMaybeMessage<::google::protobuf::GeneratedCodeInfo>(arena, *from._impl_.generated_code_info_) - : nullptr; + _impl_.generated_code_info_ = (cached_has_bits & 0x00000008u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::GeneratedCodeInfo>( + arena, *from._impl_.generated_code_info_) + : nullptr; // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse.File) } @@ -1052,12 +1027,13 @@ inline void CodeGeneratorResponse_File::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* CodeGeneratorResponse_File::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { CodeGeneratorResponse_File::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void CodeGeneratorResponse_File::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorResponse.File) @@ -1107,6 +1083,9 @@ const ::_pbi::TcParseTable<2, 4, 1, 86, 2> CodeGeneratorResponse_File::_table_ = offsetof(decltype(_table_), aux_entries), &_CodeGeneratorResponse_File_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::compiler::CodeGeneratorResponse_File>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; {::_pbi::TcParser::FastMtS2, @@ -1181,8 +1160,7 @@ const ::_pbi::TcParseTable<2, 4, 1, 86, 2> CodeGeneratorResponse_File::_table_ = // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; if (cached_has_bits & 0x00000008u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 16, _Internal::generated_code_info(this), - _Internal::generated_code_info(this).GetCachedSize(), target, stream); + 16, *_impl_.generated_code_info_, _impl_.generated_code_info_->GetCachedSize(), target, stream); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { @@ -1233,9 +1211,10 @@ const ::_pbi::TcParseTable<2, 4, 1, 86, 2> CodeGeneratorResponse_File::_table_ = } -void CodeGeneratorResponse_File::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void CodeGeneratorResponse_File::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -1253,10 +1232,16 @@ void CodeGeneratorResponse_File::MergeImpl(::google::protobuf::Message& to_msg, _this->_internal_set_content(from._internal_content()); } if (cached_has_bits & 0x00000008u) { - _this->_internal_mutable_generated_code_info()->::google::protobuf::GeneratedCodeInfo::MergeFrom( - from._internal_generated_code_info()); + ABSL_DCHECK(from._impl_.generated_code_info_ != nullptr); + if (_this->_impl_.generated_code_info_ == nullptr) { + _this->_impl_.generated_code_info_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::GeneratedCodeInfo>(arena, *from._impl_.generated_code_info_); + } else { + _this->_impl_.generated_code_info_->MergeFrom(*from._impl_.generated_code_info_); + } } } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -1271,9 +1256,6 @@ PROTOBUF_NOINLINE bool CodeGeneratorResponse_File::IsInitialized() const { return true; } -::_pbi::CachedSize* CodeGeneratorResponse_File::AccessCachedSize() const { - return &_impl_._cached_size_; -} void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -1287,9 +1269,9 @@ void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* PROTOB } ::google::protobuf::Metadata CodeGeneratorResponse_File::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, - file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[2]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, + file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[2]); } // =================================================================== @@ -1298,12 +1280,6 @@ class CodeGeneratorResponse::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_._has_bits_); - static void set_has_error(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_supported_features(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } }; CodeGeneratorResponse::CodeGeneratorResponse(::google::protobuf::Arena* arena) @@ -1328,7 +1304,13 @@ CodeGeneratorResponse::CodeGeneratorResponse( _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>( from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); - _impl_.supported_features_ = from._impl_.supported_features_; + ::memcpy(reinterpret_cast(&_impl_) + + offsetof(Impl_, supported_features_), + reinterpret_cast(&from._impl_) + + offsetof(Impl_, supported_features_), + offsetof(Impl_, maximum_edition_) - + offsetof(Impl_, supported_features_) + + sizeof(Impl_::maximum_edition_)); // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse) } @@ -1341,7 +1323,12 @@ inline PROTOBUF_NDEBUG_INLINE CodeGeneratorResponse::Impl_::Impl_( inline void CodeGeneratorResponse::SharedCtor(::_pb::Arena* arena) { new (&_impl_) Impl_(internal_visibility(), arena); - _impl_.supported_features_ = {}; + ::memset(reinterpret_cast(&_impl_) + + offsetof(Impl_, supported_features_), + 0, + offsetof(Impl_, maximum_edition_) - + offsetof(Impl_, supported_features_) + + sizeof(Impl_::maximum_edition_)); } CodeGeneratorResponse::~CodeGeneratorResponse() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse) @@ -1357,12 +1344,13 @@ inline void CodeGeneratorResponse::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* CodeGeneratorResponse::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { CodeGeneratorResponse::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void CodeGeneratorResponse::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorResponse) @@ -1376,7 +1364,11 @@ PROTOBUF_NOINLINE void CodeGeneratorResponse::Clear() { if (cached_has_bits & 0x00000001u) { _impl_.error_.ClearNonDefaultToEmpty(); } - _impl_.supported_features_ = ::uint64_t{0u}; + if (cached_has_bits & 0x0000000eu) { + ::memset(&_impl_.supported_features_, 0, static_cast<::size_t>( + reinterpret_cast(&_impl_.maximum_edition_) - + reinterpret_cast(&_impl_.supported_features_)) + sizeof(_impl_.maximum_edition_)); + } _impl_._has_bits_.Clear(); _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } @@ -1389,19 +1381,22 @@ const char* CodeGeneratorResponse::_InternalParse( PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 -const ::_pbi::TcParseTable<2, 3, 1, 60, 2> CodeGeneratorResponse::_table_ = { +const ::_pbi::TcParseTable<3, 5, 1, 60, 2> CodeGeneratorResponse::_table_ = { { PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_._has_bits_), 0, // no _extensions_ - 15, 24, // max_field_number, fast_idx_mask + 15, 56, // max_field_number, fast_idx_mask offsetof(decltype(_table_), field_lookup_table), - 4294950908, // skipmap + 4294950896, // skipmap offsetof(decltype(_table_), field_entries), - 3, // num_field_entries + 5, // num_field_entries 1, // num_aux_entries offsetof(decltype(_table_), aux_entries), &_CodeGeneratorResponse_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::compiler::CodeGeneratorResponse>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional string error = 1; @@ -1410,6 +1405,14 @@ const ::_pbi::TcParseTable<2, 3, 1, 60, 2> CodeGeneratorResponse::_table_ = { // optional uint64 supported_features = 2; {::_pbi::TcParser::SingularVarintNoZag1<::uint64_t, offsetof(CodeGeneratorResponse, _impl_.supported_features_), 1>(), {16, 1, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.supported_features_)}}, + // optional int32 minimum_edition = 3; + {::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(CodeGeneratorResponse, _impl_.minimum_edition_), 2>(), + {24, 2, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.minimum_edition_)}}, + // optional int32 maximum_edition = 4; + {::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(CodeGeneratorResponse, _impl_.maximum_edition_), 3>(), + {32, 3, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.maximum_edition_)}}, + {::_pbi::TcParser::MiniParse, {}}, + {::_pbi::TcParser::MiniParse, {}}, // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; {::_pbi::TcParser::FastMtR1, {122, 63, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.file_)}}, @@ -1422,6 +1425,12 @@ const ::_pbi::TcParseTable<2, 3, 1, 60, 2> CodeGeneratorResponse::_table_ = { // optional uint64 supported_features = 2; {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.supported_features_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kUInt64)}, + // optional int32 minimum_edition = 3; + {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.minimum_edition_), _Internal::kHasBitsOffset + 2, 0, + (0 | ::_fl::kFcOptional | ::_fl::kInt32)}, + // optional int32 maximum_edition = 4; + {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.maximum_edition_), _Internal::kHasBitsOffset + 3, 0, + (0 | ::_fl::kFcOptional | ::_fl::kInt32)}, // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.file_), -1, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, @@ -1457,6 +1466,20 @@ const ::_pbi::TcParseTable<2, 3, 1, 60, 2> CodeGeneratorResponse::_table_ = { 2, this->_internal_supported_features(), target); } + // optional int32 minimum_edition = 3; + if (cached_has_bits & 0x00000004u) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteInt32ToArrayWithField<3>( + stream, this->_internal_minimum_edition(), target); + } + + // optional int32 maximum_edition = 4; + if (cached_has_bits & 0x00000008u) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteInt32ToArrayWithField<4>( + stream, this->_internal_maximum_edition(), target); + } + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; for (unsigned i = 0, n = static_cast(this->_internal_file_size()); i < n; i++) { @@ -1489,7 +1512,7 @@ const ::_pbi::TcParseTable<2, 3, 1, 60, 2> CodeGeneratorResponse::_table_ = { ::google::protobuf::internal::WireFormatLite::MessageSize(msg); } cached_has_bits = _impl_._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x0000000fu) { // optional string error = 1; if (cached_has_bits & 0x00000001u) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize( @@ -1502,12 +1525,24 @@ const ::_pbi::TcParseTable<2, 3, 1, 60, 2> CodeGeneratorResponse::_table_ = { this->_internal_supported_features()); } + // optional int32 minimum_edition = 3; + if (cached_has_bits & 0x00000004u) { + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne( + this->_internal_minimum_edition()); + } + + // optional int32 maximum_edition = 4; + if (cached_has_bits & 0x00000008u) { + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne( + this->_internal_maximum_edition()); + } + } return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_); } -void CodeGeneratorResponse::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void CodeGeneratorResponse::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse) @@ -1518,15 +1553,21 @@ void CodeGeneratorResponse::MergeImpl(::google::protobuf::Message& to_msg, const _this->_internal_mutable_file()->MergeFrom( from._internal_file()); cached_has_bits = from._impl_._has_bits_[0]; - if (cached_has_bits & 0x00000003u) { + if (cached_has_bits & 0x0000000fu) { if (cached_has_bits & 0x00000001u) { _this->_internal_set_error(from._internal_error()); } if (cached_has_bits & 0x00000002u) { _this->_impl_.supported_features_ = from._impl_.supported_features_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; + if (cached_has_bits & 0x00000004u) { + _this->_impl_.minimum_edition_ = from._impl_.minimum_edition_; + } + if (cached_has_bits & 0x00000008u) { + _this->_impl_.maximum_edition_ = from._impl_.maximum_edition_; + } } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -1541,9 +1582,6 @@ PROTOBUF_NOINLINE bool CodeGeneratorResponse::IsInitialized() const { return true; } -::_pbi::CachedSize* CodeGeneratorResponse::AccessCachedSize() const { - return &_impl_._cached_size_; -} void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -1552,13 +1590,18 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* PROTOBUF_RESTRIC swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); _impl_.file_.InternalSwap(&other->_impl_.file_); ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.error_, &other->_impl_.error_, arena); - swap(_impl_.supported_features_, other->_impl_.supported_features_); + ::google::protobuf::internal::memswap< + PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.maximum_edition_) + + sizeof(CodeGeneratorResponse::_impl_.maximum_edition_) + - PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.supported_features_)>( + reinterpret_cast(&_impl_.supported_features_), + reinterpret_cast(&other->_impl_.supported_features_)); } ::google::protobuf::Metadata CodeGeneratorResponse::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, - file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[3]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once, + file_level_metadata_google_2fprotobuf_2fcompiler_2fplugin_2eproto[3]); } // @@protoc_insertion_point(namespace_scope) } // namespace compiler @@ -1569,4 +1612,8 @@ namespace protobuf { } // namespace protobuf } // namespace google // @@protoc_insertion_point(global_scope) +PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 +static ::std::false_type _static_init_ PROTOBUF_UNUSED = + (::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto), + ::std::false_type{}); #include "google/protobuf/port_undef.inc" diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index eb3da21003..7b036ff754 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -1,6 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/compiler/plugin.proto -// Protobuf C++ Version: 4.24.0-main +// Protobuf C++ Version: 4.26.0-dev #ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto_2epb_2eh #define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto_2epb_2eh @@ -11,17 +11,11 @@ #include #include "google/protobuf/port_def.inc" -#if PROTOBUF_VERSION < 4024000 -#error "This file was generated by a newer version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please update" -#error "your headers." -#endif // PROTOBUF_VERSION - -#if 4024000 < PROTOBUF_MIN_PROTOC_VERSION -#error "This file was generated by an older version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please" -#error "regenerate this file with a newer version of protoc." -#endif // PROTOBUF_MIN_PROTOC_VERSION +#if PROTOBUF_VERSION != 4026000 +#error "Protobuf C++ gencode is built with an incompatible version of" +#error "Protobuf C++ headers/runtime. See" +#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp" +#endif #include "google/protobuf/port_undef.inc" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/arena.h" @@ -121,21 +115,18 @@ inline bool CodeGeneratorResponse_Feature_Parse(absl::string_view name, CodeGene // ------------------------------------------------------------------- -class PROTOC_EXPORT Version final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.Version) */ { +class PROTOC_EXPORT Version final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.compiler.Version) */ { public: inline Version() : Version(nullptr) {} ~Version() override; - template - explicit PROTOBUF_CONSTEXPR Version(::google::protobuf::internal::ConstantInitialized); - - inline Version(const Version& from) - : Version(nullptr, from) {} - Version(Version&& from) noexcept - : Version() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR Version( + ::google::protobuf::internal::ConstantInitialized); + inline Version(const Version& from) : Version(nullptr, from) {} + inline Version(Version&& from) noexcept + : Version(nullptr, std::move(from)) {} inline Version& operator=(const Version& from) { CopyFrom(from); return *this; @@ -143,9 +134,9 @@ class PROTOC_EXPORT Version final : inline Version& operator=(Version&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -177,22 +168,17 @@ class PROTOC_EXPORT Version final : } static inline const Version* internal_default_instance() { return reinterpret_cast( - &_Version_default_instance_); - } - static constexpr int kIndexInFileMessages = - 0; - - friend void swap(Version& a, Version& b) { - a.Swap(&b); + &_Version_default_instance_); } + static constexpr int kIndexInFileMessages = 0; + friend void swap(Version& a, Version& b) { a.Swap(&b); } inline void Swap(Version* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -207,16 +193,18 @@ class PROTOC_EXPORT Version final : // implements Message ---------------------------------------------- Version* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const Version& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const Version& from) { - Version::MergeImpl(*this, from); - } + void MergeFrom(const Version& from) { Version::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -224,32 +212,33 @@ class PROTOC_EXPORT Version final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(Version* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.compiler.Version"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.compiler.Version"; } + + protected: explicit Version(::google::protobuf::Arena* arena); Version(::google::protobuf::Arena* arena, const Version& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + Version(::google::protobuf::Arena* arena, Version&& from) noexcept + : Version(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kSuffixFieldNumber = 4, kMajorFieldNumber = 1, @@ -309,7 +298,6 @@ class PROTOC_EXPORT Version final : // @@protoc_insertion_point(class_scope:google.protobuf.compiler.Version) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 2, 4, 0, @@ -321,14 +309,13 @@ class PROTOC_EXPORT Version final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOC_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::internal::ArenaStringPtr suffix_; @@ -339,23 +326,21 @@ class PROTOC_EXPORT Version final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOC_EXPORT CodeGeneratorResponse_File final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse.File) */ { +class PROTOC_EXPORT CodeGeneratorResponse_File final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse.File) */ { public: inline CodeGeneratorResponse_File() : CodeGeneratorResponse_File(nullptr) {} ~CodeGeneratorResponse_File() override; - template - explicit PROTOBUF_CONSTEXPR CodeGeneratorResponse_File(::google::protobuf::internal::ConstantInitialized); - - inline CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from) - : CodeGeneratorResponse_File(nullptr, from) {} - CodeGeneratorResponse_File(CodeGeneratorResponse_File&& from) noexcept - : CodeGeneratorResponse_File() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR CodeGeneratorResponse_File( + ::google::protobuf::internal::ConstantInitialized); + inline CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from) : CodeGeneratorResponse_File(nullptr, from) {} + inline CodeGeneratorResponse_File(CodeGeneratorResponse_File&& from) noexcept + : CodeGeneratorResponse_File(nullptr, std::move(from)) {} inline CodeGeneratorResponse_File& operator=(const CodeGeneratorResponse_File& from) { CopyFrom(from); return *this; @@ -363,9 +348,9 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : inline CodeGeneratorResponse_File& operator=(CodeGeneratorResponse_File&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -397,22 +382,17 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : } static inline const CodeGeneratorResponse_File* internal_default_instance() { return reinterpret_cast( - &_CodeGeneratorResponse_File_default_instance_); - } - static constexpr int kIndexInFileMessages = - 2; - - friend void swap(CodeGeneratorResponse_File& a, CodeGeneratorResponse_File& b) { - a.Swap(&b); + &_CodeGeneratorResponse_File_default_instance_); } + static constexpr int kIndexInFileMessages = 2; + friend void swap(CodeGeneratorResponse_File& a, CodeGeneratorResponse_File& b) { a.Swap(&b); } inline void Swap(CodeGeneratorResponse_File* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -427,16 +407,18 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : // implements Message ---------------------------------------------- CodeGeneratorResponse_File* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const CodeGeneratorResponse_File& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const CodeGeneratorResponse_File& from) { - CodeGeneratorResponse_File::MergeImpl(*this, from); - } + void MergeFrom(const CodeGeneratorResponse_File& from) { CodeGeneratorResponse_File::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -444,32 +426,33 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(CodeGeneratorResponse_File* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.compiler.CodeGeneratorResponse.File"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.compiler.CodeGeneratorResponse.File"; } + + protected: explicit CodeGeneratorResponse_File(::google::protobuf::Arena* arena); CodeGeneratorResponse_File(::google::protobuf::Arena* arena, const CodeGeneratorResponse_File& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + CodeGeneratorResponse_File(::google::protobuf::Arena* arena, CodeGeneratorResponse_File&& from) noexcept + : CodeGeneratorResponse_File(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kNameFieldNumber = 1, kInsertionPointFieldNumber = 2, @@ -545,7 +528,6 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 2, 4, 1, @@ -557,14 +539,13 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOC_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::internal::ArenaStringPtr name_; @@ -575,23 +556,21 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOC_EXPORT CodeGeneratorResponse final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse) */ { +class PROTOC_EXPORT CodeGeneratorResponse final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse) */ { public: inline CodeGeneratorResponse() : CodeGeneratorResponse(nullptr) {} ~CodeGeneratorResponse() override; - template - explicit PROTOBUF_CONSTEXPR CodeGeneratorResponse(::google::protobuf::internal::ConstantInitialized); - - inline CodeGeneratorResponse(const CodeGeneratorResponse& from) - : CodeGeneratorResponse(nullptr, from) {} - CodeGeneratorResponse(CodeGeneratorResponse&& from) noexcept - : CodeGeneratorResponse() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR CodeGeneratorResponse( + ::google::protobuf::internal::ConstantInitialized); + inline CodeGeneratorResponse(const CodeGeneratorResponse& from) : CodeGeneratorResponse(nullptr, from) {} + inline CodeGeneratorResponse(CodeGeneratorResponse&& from) noexcept + : CodeGeneratorResponse(nullptr, std::move(from)) {} inline CodeGeneratorResponse& operator=(const CodeGeneratorResponse& from) { CopyFrom(from); return *this; @@ -599,9 +578,9 @@ class PROTOC_EXPORT CodeGeneratorResponse final : inline CodeGeneratorResponse& operator=(CodeGeneratorResponse&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -633,22 +612,17 @@ class PROTOC_EXPORT CodeGeneratorResponse final : } static inline const CodeGeneratorResponse* internal_default_instance() { return reinterpret_cast( - &_CodeGeneratorResponse_default_instance_); - } - static constexpr int kIndexInFileMessages = - 3; - - friend void swap(CodeGeneratorResponse& a, CodeGeneratorResponse& b) { - a.Swap(&b); + &_CodeGeneratorResponse_default_instance_); } + static constexpr int kIndexInFileMessages = 3; + friend void swap(CodeGeneratorResponse& a, CodeGeneratorResponse& b) { a.Swap(&b); } inline void Swap(CodeGeneratorResponse* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -663,16 +637,18 @@ class PROTOC_EXPORT CodeGeneratorResponse final : // implements Message ---------------------------------------------- CodeGeneratorResponse* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const CodeGeneratorResponse& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const CodeGeneratorResponse& from) { - CodeGeneratorResponse::MergeImpl(*this, from); - } + void MergeFrom(const CodeGeneratorResponse& from) { CodeGeneratorResponse::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -680,32 +656,32 @@ class PROTOC_EXPORT CodeGeneratorResponse final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(CodeGeneratorResponse* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.compiler.CodeGeneratorResponse"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.compiler.CodeGeneratorResponse"; } + + protected: explicit CodeGeneratorResponse(::google::protobuf::Arena* arena); CodeGeneratorResponse(::google::protobuf::Arena* arena, const CodeGeneratorResponse& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + CodeGeneratorResponse(::google::protobuf::Arena* arena, CodeGeneratorResponse&& from) noexcept + : CodeGeneratorResponse(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- - using File = CodeGeneratorResponse_File; - using Feature = CodeGeneratorResponse_Feature; static constexpr Feature FEATURE_NONE = CodeGeneratorResponse_Feature_FEATURE_NONE; static constexpr Feature FEATURE_PROTO3_OPTIONAL = CodeGeneratorResponse_Feature_FEATURE_PROTO3_OPTIONAL; @@ -728,11 +704,12 @@ class PROTOC_EXPORT CodeGeneratorResponse final : } // accessors ------------------------------------------------------- - enum : int { kFileFieldNumber = 15, kErrorFieldNumber = 1, kSupportedFeaturesFieldNumber = 2, + kMinimumEditionFieldNumber = 3, + kMaximumEditionFieldNumber = 4, }; // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; int file_size() const; @@ -742,16 +719,15 @@ class PROTOC_EXPORT CodeGeneratorResponse final : public: void clear_file() ; ::google::protobuf::compiler::CodeGeneratorResponse_File* mutable_file(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >* - mutable_file(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::compiler::CodeGeneratorResponse_File>* mutable_file(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::compiler::CodeGeneratorResponse_File>& _internal_file() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::compiler::CodeGeneratorResponse_File>* _internal_mutable_file(); public: const ::google::protobuf::compiler::CodeGeneratorResponse_File& file(int index) const; ::google::protobuf::compiler::CodeGeneratorResponse_File* add_file(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >& - file() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::compiler::CodeGeneratorResponse_File>& file() const; // optional string error = 1; bool has_error() const; void clear_error() ; @@ -779,14 +755,35 @@ class PROTOC_EXPORT CodeGeneratorResponse final : ::uint64_t _internal_supported_features() const; void _internal_set_supported_features(::uint64_t value); + public: + // optional int32 minimum_edition = 3; + bool has_minimum_edition() const; + void clear_minimum_edition() ; + ::int32_t minimum_edition() const; + void set_minimum_edition(::int32_t value); + + private: + ::int32_t _internal_minimum_edition() const; + void _internal_set_minimum_edition(::int32_t value); + + public: + // optional int32 maximum_edition = 4; + bool has_maximum_edition() const; + void clear_maximum_edition() ; + ::int32_t maximum_edition() const; + void set_maximum_edition(::int32_t value); + + private: + ::int32_t _internal_maximum_edition() const; + void _internal_set_maximum_edition(::int32_t value); + public: // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< - 2, 3, 1, + 3, 5, 1, 60, 2> _table_; friend class ::google::protobuf::MessageLite; @@ -795,40 +792,39 @@ class PROTOC_EXPORT CodeGeneratorResponse final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOC_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File > file_; ::google::protobuf::internal::ArenaStringPtr error_; ::uint64_t supported_features_; + ::int32_t minimum_edition_; + ::int32_t maximum_edition_; PROTOBUF_TSAN_DECLARE_MEMBER }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOC_EXPORT CodeGeneratorRequest final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorRequest) */ { +class PROTOC_EXPORT CodeGeneratorRequest final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorRequest) */ { public: inline CodeGeneratorRequest() : CodeGeneratorRequest(nullptr) {} ~CodeGeneratorRequest() override; - template - explicit PROTOBUF_CONSTEXPR CodeGeneratorRequest(::google::protobuf::internal::ConstantInitialized); - - inline CodeGeneratorRequest(const CodeGeneratorRequest& from) - : CodeGeneratorRequest(nullptr, from) {} - CodeGeneratorRequest(CodeGeneratorRequest&& from) noexcept - : CodeGeneratorRequest() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR CodeGeneratorRequest( + ::google::protobuf::internal::ConstantInitialized); + inline CodeGeneratorRequest(const CodeGeneratorRequest& from) : CodeGeneratorRequest(nullptr, from) {} + inline CodeGeneratorRequest(CodeGeneratorRequest&& from) noexcept + : CodeGeneratorRequest(nullptr, std::move(from)) {} inline CodeGeneratorRequest& operator=(const CodeGeneratorRequest& from) { CopyFrom(from); return *this; @@ -836,9 +832,9 @@ class PROTOC_EXPORT CodeGeneratorRequest final : inline CodeGeneratorRequest& operator=(CodeGeneratorRequest&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -870,22 +866,17 @@ class PROTOC_EXPORT CodeGeneratorRequest final : } static inline const CodeGeneratorRequest* internal_default_instance() { return reinterpret_cast( - &_CodeGeneratorRequest_default_instance_); - } - static constexpr int kIndexInFileMessages = - 1; - - friend void swap(CodeGeneratorRequest& a, CodeGeneratorRequest& b) { - a.Swap(&b); + &_CodeGeneratorRequest_default_instance_); } + static constexpr int kIndexInFileMessages = 1; + friend void swap(CodeGeneratorRequest& a, CodeGeneratorRequest& b) { a.Swap(&b); } inline void Swap(CodeGeneratorRequest* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -900,16 +891,18 @@ class PROTOC_EXPORT CodeGeneratorRequest final : // implements Message ---------------------------------------------- CodeGeneratorRequest* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const CodeGeneratorRequest& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const CodeGeneratorRequest& from) { - CodeGeneratorRequest::MergeImpl(*this, from); - } + void MergeFrom(const CodeGeneratorRequest& from) { CodeGeneratorRequest::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -917,32 +910,33 @@ class PROTOC_EXPORT CodeGeneratorRequest final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(CodeGeneratorRequest* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.compiler.CodeGeneratorRequest"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.compiler.CodeGeneratorRequest"; } + + protected: explicit CodeGeneratorRequest(::google::protobuf::Arena* arena); CodeGeneratorRequest(::google::protobuf::Arena* arena, const CodeGeneratorRequest& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + CodeGeneratorRequest(::google::protobuf::Arena* arena, CodeGeneratorRequest&& from) noexcept + : CodeGeneratorRequest(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kFileToGenerateFieldNumber = 1, kProtoFileFieldNumber = 15, @@ -986,16 +980,15 @@ class PROTOC_EXPORT CodeGeneratorRequest final : public: void clear_proto_file() ; ::google::protobuf::FileDescriptorProto* mutable_proto_file(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* - mutable_proto_file(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* mutable_proto_file(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& _internal_proto_file() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* _internal_mutable_proto_file(); public: const ::google::protobuf::FileDescriptorProto& proto_file(int index) const; ::google::protobuf::FileDescriptorProto* add_proto_file(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& - proto_file() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& proto_file() const; // repeated .google.protobuf.FileDescriptorProto source_file_descriptors = 17; int source_file_descriptors_size() const; private: @@ -1004,16 +997,15 @@ class PROTOC_EXPORT CodeGeneratorRequest final : public: void clear_source_file_descriptors() ; ::google::protobuf::FileDescriptorProto* mutable_source_file_descriptors(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* - mutable_source_file_descriptors(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* mutable_source_file_descriptors(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& _internal_source_file_descriptors() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* _internal_mutable_source_file_descriptors(); public: const ::google::protobuf::FileDescriptorProto& source_file_descriptors(int index) const; ::google::protobuf::FileDescriptorProto* add_source_file_descriptors(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& - source_file_descriptors() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& source_file_descriptors() const; // optional string parameter = 2; bool has_parameter() const; void clear_parameter() ; @@ -1049,7 +1041,6 @@ class PROTOC_EXPORT CodeGeneratorRequest final : // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 3, 5, 3, @@ -1061,14 +1052,13 @@ class PROTOC_EXPORT CodeGeneratorRequest final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOC_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField file_to_generate_; @@ -1114,6 +1104,7 @@ inline ::int32_t Version::major() const { } inline void Version::set_major(::int32_t value) { _internal_set_major(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.major) } inline ::int32_t Version::_internal_major() const { @@ -1122,7 +1113,6 @@ inline ::int32_t Version::_internal_major() const { } inline void Version::_internal_set_major(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.major_ = value; } @@ -1142,6 +1132,7 @@ inline ::int32_t Version::minor() const { } inline void Version::set_minor(::int32_t value) { _internal_set_minor(value); + _impl_._has_bits_[0] |= 0x00000004u; // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.minor) } inline ::int32_t Version::_internal_minor() const { @@ -1150,7 +1141,6 @@ inline ::int32_t Version::_internal_minor() const { } inline void Version::_internal_set_minor(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000004u; _impl_.minor_ = value; } @@ -1170,6 +1160,7 @@ inline ::int32_t Version::patch() const { } inline void Version::set_patch(::int32_t value) { _internal_set_patch(value); + _impl_._has_bits_[0] |= 0x00000008u; // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.patch) } inline ::int32_t Version::_internal_patch() const { @@ -1178,7 +1169,6 @@ inline ::int32_t Version::_internal_patch() const { } inline void Version::_internal_set_patch(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000008u; _impl_.patch_ = value; } @@ -1582,14 +1572,14 @@ inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::unsafe_arena } inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::_internal_mutable_compiler_version() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; if (_impl_.compiler_version_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::compiler::Version>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::compiler::Version>(GetArena()); _impl_.compiler_version_ = reinterpret_cast<::google::protobuf::compiler::Version*>(p); } return _impl_.compiler_version_; } inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::mutable_compiler_version() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000002u; ::google::protobuf::compiler::Version* _msg = _internal_mutable_compiler_version(); // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.compiler_version) return _msg; @@ -1890,14 +1880,14 @@ inline ::google::protobuf::GeneratedCodeInfo* CodeGeneratorResponse_File::unsafe } inline ::google::protobuf::GeneratedCodeInfo* CodeGeneratorResponse_File::_internal_mutable_generated_code_info() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000008u; if (_impl_.generated_code_info_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::GeneratedCodeInfo>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::GeneratedCodeInfo>(GetArena()); _impl_.generated_code_info_ = reinterpret_cast<::google::protobuf::GeneratedCodeInfo*>(p); } return _impl_.generated_code_info_; } inline ::google::protobuf::GeneratedCodeInfo* CodeGeneratorResponse_File::mutable_generated_code_info() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000008u; ::google::protobuf::GeneratedCodeInfo* _msg = _internal_mutable_generated_code_info(); // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info) return _msg; @@ -2014,6 +2004,7 @@ inline ::uint64_t CodeGeneratorResponse::supported_features() const { } inline void CodeGeneratorResponse::set_supported_features(::uint64_t value) { _internal_set_supported_features(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.supported_features) } inline ::uint64_t CodeGeneratorResponse::_internal_supported_features() const { @@ -2022,10 +2013,65 @@ inline ::uint64_t CodeGeneratorResponse::_internal_supported_features() const { } inline void CodeGeneratorResponse::_internal_set_supported_features(::uint64_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.supported_features_ = value; } +// optional int32 minimum_edition = 3; +inline bool CodeGeneratorResponse::has_minimum_edition() const { + bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0; + return value; +} +inline void CodeGeneratorResponse::clear_minimum_edition() { + PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); + _impl_.minimum_edition_ = 0; + _impl_._has_bits_[0] &= ~0x00000004u; +} +inline ::int32_t CodeGeneratorResponse::minimum_edition() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.minimum_edition) + return _internal_minimum_edition(); +} +inline void CodeGeneratorResponse::set_minimum_edition(::int32_t value) { + _internal_set_minimum_edition(value); + _impl_._has_bits_[0] |= 0x00000004u; + // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.minimum_edition) +} +inline ::int32_t CodeGeneratorResponse::_internal_minimum_edition() const { + PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race); + return _impl_.minimum_edition_; +} +inline void CodeGeneratorResponse::_internal_set_minimum_edition(::int32_t value) { + PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); + _impl_.minimum_edition_ = value; +} + +// optional int32 maximum_edition = 4; +inline bool CodeGeneratorResponse::has_maximum_edition() const { + bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0; + return value; +} +inline void CodeGeneratorResponse::clear_maximum_edition() { + PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); + _impl_.maximum_edition_ = 0; + _impl_._has_bits_[0] &= ~0x00000008u; +} +inline ::int32_t CodeGeneratorResponse::maximum_edition() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.maximum_edition) + return _internal_maximum_edition(); +} +inline void CodeGeneratorResponse::set_maximum_edition(::int32_t value) { + _internal_set_maximum_edition(value); + _impl_._has_bits_[0] |= 0x00000008u; + // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.maximum_edition) +} +inline ::int32_t CodeGeneratorResponse::_internal_maximum_edition() const { + PROTOBUF_TSAN_READ(&_impl_._tsan_detect_race); + return _impl_.maximum_edition_; +} +inline void CodeGeneratorResponse::_internal_set_maximum_edition(::int32_t value) { + PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); + _impl_.maximum_edition_ = value; +} + // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; inline int CodeGeneratorResponse::_internal_file_size() const { return _internal_file().size(); diff --git a/src/google/protobuf/compiler/plugin.proto b/src/google/protobuf/compiler/plugin.proto index 829cf41299..033fab23cc 100644 --- a/src/google/protobuf/compiler/plugin.proto +++ b/src/google/protobuf/compiler/plugin.proto @@ -102,6 +102,18 @@ message CodeGeneratorResponse { FEATURE_SUPPORTS_EDITIONS = 2; } + // The minimum edition this plugin supports. This will be treated as an + // Edition enum, but we want to allow unknown values. It should be specified + // according the edition enum value, *not* the edition number. Only takes + // effect for plugins that have FEATURE_SUPPORTS_EDITIONS set. + optional int32 minimum_edition = 3; + + // The maximum edition this plugin supports. This will be treated as an + // Edition enum, but we want to allow unknown values. It should be specified + // according the edition enum value, *not* the edition number. Only takes + // effect for plugins that have FEATURE_SUPPORTS_EDITIONS set. + optional int32 maximum_edition = 4; + // Represents a single generated file. message File { // The file name, relative to the output directory. The name must not diff --git a/src/google/protobuf/compiler/python/BUILD.bazel b/src/google/protobuf/compiler/python/BUILD.bazel index e9501f2b56..5fe960417a 100644 --- a/src/google/protobuf/compiler/python/BUILD.bazel +++ b/src/google/protobuf/compiler/python/BUILD.bazel @@ -26,7 +26,6 @@ cc_library( "@com_github_grpc_grpc//tools/distrib/python/grpcio_tools:__subpackages__", ], deps = [ - "//src/google/protobuf:descriptor_legacy", "//src/google/protobuf:protobuf_nowkt", "//src/google/protobuf/compiler:code_generator", "//src/google/protobuf/compiler:retention", diff --git a/src/google/protobuf/compiler/python/generator.cc b/src/google/protobuf/compiler/python/generator.cc index f3cce736d6..555e4edef1 100644 --- a/src/google/protobuf/compiler/python/generator.cc +++ b/src/google/protobuf/compiler/python/generator.cc @@ -21,7 +21,7 @@ #include "google/protobuf/compiler/python/generator.h" -#include +#include #include #include #include @@ -31,24 +31,29 @@ #include "absl/container/flat_hash_map.h" #include "absl/log/absl_check.h" #include "absl/log/absl_log.h" +#include "absl/memory/memory.h" #include "absl/strings/ascii.h" #include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" +#include "absl/strings/str_join.h" #include "absl/strings/str_replace.h" #include "absl/strings/string_view.h" #include "absl/strings/strip.h" #include "absl/strings/substitute.h" +#include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/compiler/python/helpers.h" #include "google/protobuf/compiler/python/pyi_generator.h" #include "google/protobuf/compiler/retention.h" #include "google/protobuf/compiler/versions.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" -#include "google/protobuf/descriptor_legacy.h" +#include "google/protobuf/descriptor_visitor.h" +#include "google/protobuf/dynamic_message.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/io/strtod.h" #include "google/protobuf/io/zero_copy_stream.h" +#include "google/protobuf/message.h" namespace google { namespace protobuf { @@ -152,18 +157,23 @@ std::string StringifyDefaultValue(const FieldDescriptor& field) { return ""; } -std::string StringifySyntax(FileDescriptorLegacy::Syntax syntax) { - switch (syntax) { - case FileDescriptorLegacy::Syntax::SYNTAX_PROTO2: +// Returns a CEscaped string of serialized_options. +std::string OptionsValue(absl::string_view serialized_options) { + if (serialized_options.empty()) { + return "None"; + } else { + return absl::StrCat("b'", absl::CEscape(serialized_options), "'"); + } +} + +std::string GetLegacySyntaxName(Edition edition) { + switch (edition) { + case Edition::EDITION_PROTO2: return "proto2"; - case FileDescriptorLegacy::Syntax::SYNTAX_PROTO3: + case Edition::EDITION_PROTO3: return "proto3"; - case FileDescriptorLegacy::Syntax::SYNTAX_UNKNOWN: default: - ABSL_LOG(FATAL) - << "Unsupported syntax; this generator only supports proto2 " - "and proto3 syntax."; - return ""; + return "editions"; } } @@ -173,10 +183,6 @@ Generator::Generator() : file_(nullptr) {} Generator::~Generator() {} -uint64_t Generator::GetSupportedFeatures() const { - return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL; -} - GeneratorOptions Generator::ParseParameter(absl::string_view parameter, std::string* error) const { GeneratorOptions options; @@ -194,6 +200,8 @@ GeneratorOptions Generator::ParseParameter(absl::string_view parameter, options.generate_pyi = true; } else if (option.first == "annotate_code") { options.annotate_pyi = true; + } else if (option.first == "experimental_strip_nonfunctional_codegen") { + options.strip_nonfunctional_codegen = true; } else { *error = absl::StrCat("Unknown generator option: ", option.first); } @@ -211,8 +219,15 @@ bool Generator::Generate(const FileDescriptor* file, // Generate pyi typing information if (options.generate_pyi) { python::PyiGenerator pyi_generator; - std::string pyi_options = options.annotate_pyi ? "annotate_code" : ""; - if (!pyi_generator.Generate(file, pyi_options, context, error)) { + std::vector pyi_options; + if (options.annotate_pyi) { + pyi_options.push_back("annotate_code"); + } + if (options.strip_nonfunctional_codegen) { + pyi_options.push_back("experimental_strip_nonfunctional_codegen"); + } + if (!pyi_generator.Generate(file, absl::StrJoin(pyi_options, ","), context, + error)) { return false; } } @@ -229,8 +244,8 @@ bool Generator::Generate(const FileDescriptor* file, std::string filename = GetFileName(file, ".py"); - FileDescriptorProto fdp = StripSourceRetentionOptions(*file_); - fdp.SerializeToString(&file_descriptor_serialized_); + proto_ = StripSourceRetentionOptions(*file_); + proto_.SerializeToString(&file_descriptor_serialized_); if (!opensource_runtime_ && GeneratingDescriptorProto()) { std::string bootstrap_filename = @@ -286,6 +301,7 @@ bool Generator::Generate(const FileDescriptor* file, PrintAllEnumsInFile(); PrintMessageDescriptors(); FixForeignFieldsInDescriptors(); + PrintResolvedFeatures(); printer_->Outdent(); printer_->Print("else:\n"); printer_->Indent(); @@ -317,7 +333,7 @@ bool Generator::Generate(const FileDescriptor* file, FixAllDescriptorOptions(); // Set serialized_start and serialized_end. - SetSerializedPbInterval(fdp); + SetSerializedPbInterval(proto_); printer_->Outdent(); if (HasGenericServices(file)) { @@ -417,15 +433,120 @@ void Generator::PrintImports() const { printer_->Print("\n"); } +template +std::string Generator::GetResolvedFeatures( + const DescriptorT& descriptor) const { + if (!GeneratingDescriptorProto()) { + // Everything but descriptor.proto can handle proper feature resolution. + return "None"; + } + + // Load the resolved features from our pool. + const Descriptor* feature_set = file_->pool()->FindMessageTypeByName( + FeatureSet::GetDescriptor()->full_name()); + auto message_factory = absl::make_unique(); + auto features = + absl::WrapUnique(message_factory->GetPrototype(feature_set)->New()); + features->ParseFromString( + GetResolvedSourceFeatures(descriptor).SerializeAsString()); + + // Collect all of the resolved features. + std::vector feature_args; + const Reflection* reflection = features->GetReflection(); + std::vector fields; + reflection->ListFields(*features, &fields); + for (const auto* field : fields) { + // Assume these are all enums. If we add non-enum global features or any + // python-specific features, we will need to come back and improve this + // logic. + ABSL_CHECK(field->enum_type() != nullptr) + << "Unexpected non-enum field found!"; + if (field->options().retention() == FieldOptions::RETENTION_SOURCE) { + // Skip any source-retention features. + continue; + } + const EnumDescriptor* enm = field->enum_type(); + const EnumValueDescriptor* value = + enm->FindValueByNumber(reflection->GetEnumValue(*features, field)); + + feature_args.emplace_back(absl::StrCat( + field->name(), "=", + absl::StrFormat("%s.values_by_name[\"%s\"].number", + ModuleLevelDescriptorName(*enm), value->name()))); + } + return absl::StrCat("_ResolvedFeatures(", absl::StrJoin(feature_args, ","), + ")"); +} + +void Generator::PrintResolvedFeatures() const { + // Since features are used during the descriptor build, it's impossible to do + // feature resolution at the normal point for descriptor.proto. Instead, we do + // feature resolution here in the generator, and embed a custom object on all + // of the generated descriptors. This object should act like any other + // FeatureSet message on normal descriptors, but will never have to be + // resolved by the python runtime. + ABSL_CHECK(GeneratingDescriptorProto()); + printer_->Emit({{"resolved_features", GetResolvedFeatures(*file_)}, + {"descriptor_name", kDescriptorKey}}, + R"py( + class _ResolvedFeatures: + def __init__(self, features = None, **kwargs): + if features: + for k, v in features.FIELDS.items(): + setattr(self, k, getattr(features, k)) + else: + for k, v in kwargs.items(): + setattr(self, k, v) + $descriptor_name$._features = $resolved_features$ + )py"); + +#define MAKE_NESTED(desc, CPP_FIELD, PY_FIELD) \ + [&] { \ + for (int i = 0; i < desc.CPP_FIELD##_count(); ++i) { \ + printer_->Emit( \ + {{"resolved_subfeatures", GetResolvedFeatures(*desc.CPP_FIELD(i))}, \ + {"index", absl::StrCat(i)}, \ + {"field", PY_FIELD}}, \ + "$descriptor_name$.$field$[$index$]._features = " \ + "$resolved_subfeatures$\n"); \ + } \ + } + + google::protobuf::internal::VisitDescriptors(*file_, [&](const Descriptor& msg) { + printer_->Emit( + {{"resolved_features", GetResolvedFeatures(msg)}, + {"descriptor_name", ModuleLevelDescriptorName(msg)}, + {"field_features", MAKE_NESTED(msg, field, "fields")}, + {"oneof_features", MAKE_NESTED(msg, oneof_decl, "oneofs")}, + {"ext_features", MAKE_NESTED(msg, extension, "extensions")}}, + R"py( + $descriptor_name$._features = $resolved_features$ + $field_features$ + $oneof_features$ + $ext_features$ + )py"); + }); + google::protobuf::internal::VisitDescriptors(*file_, [&](const EnumDescriptor& enm) { + printer_->Emit({{"resolved_features", GetResolvedFeatures(enm)}, + {"descriptor_name", ModuleLevelDescriptorName(enm)}, + {"value_features", MAKE_NESTED(enm, value, "values")}}, + R"py( + $descriptor_name$._features = $resolved_features$ + $value_features$ + )py"); + }); +#undef MAKE_NESTED +} + // Prints the single file descriptor for this file. void Generator::PrintFileDescriptor() const { absl::flat_hash_map m; m["descriptor_name"] = kDescriptorKey; m["name"] = file_->name(); m["package"] = file_->package(); - m["syntax"] = StringifySyntax(FileDescriptorLegacy(file_).syntax()); - m["options"] = OptionsValue( - StripLocalSourceRetentionOptions(*file_).SerializeAsString()); + m["syntax"] = GetLegacySyntaxName(file_->edition()); + m["edition"] = Edition_Name(file_->edition()); + m["options"] = OptionsValue(proto_.options().SerializeAsString()); m["serialized_descriptor"] = absl::CHexEscape(file_descriptor_serialized_); if (GeneratingDescriptorProto()) { printer_->Print("if _descriptor._USE_C_DESCRIPTORS == False:\n"); @@ -438,6 +559,7 @@ void Generator::PrintFileDescriptor() const { " name='$name$',\n" " package='$package$',\n" " syntax='$syntax$',\n" + " edition='$edition$',\n" " serialized_options=$options$,\n" " create_key=_descriptor._internal_create_key,\n"; printer_->Print(m, file_descriptor_template); @@ -487,17 +609,18 @@ void Generator::PrintFileDescriptor() const { // Prints all enums contained in all message types in |file|. void Generator::PrintAllEnumsInFile() const { for (int i = 0; i < file_->enum_type_count(); ++i) { - PrintEnum(*file_->enum_type(i)); + PrintEnum(*file_->enum_type(i), proto_.enum_type(i)); } for (int i = 0; i < file_->message_type_count(); ++i) { - PrintNestedEnums(*file_->message_type(i)); + PrintNestedEnums(*file_->message_type(i), proto_.message_type(i)); } } // Prints a Python statement assigning the appropriate module-level // enum name to a Python EnumDescriptor object equivalent to // enum_descriptor. -void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { +void Generator::PrintEnum(const EnumDescriptor& enum_descriptor, + const EnumDescriptorProto& proto) const { absl::flat_hash_map m; std::string module_level_descriptor_name = ModuleLevelDescriptorName(enum_descriptor); @@ -514,14 +637,13 @@ void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { " create_key=_descriptor._internal_create_key,\n" " values=[\n"; std::string options_string; - StripLocalSourceRetentionOptions(enum_descriptor) - .SerializeToString(&options_string); + proto.options().SerializeToString(&options_string); printer_->Print(m, enum_descriptor_template); printer_->Indent(); printer_->Indent(); for (int i = 0; i < enum_descriptor.value_count(); ++i) { - PrintEnumValueDescriptor(*enum_descriptor.value(i)); + PrintEnumValueDescriptor(*enum_descriptor.value(i), proto.value(i)); printer_->Print(",\n"); } @@ -540,20 +662,21 @@ void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const { // Recursively prints enums in nested types within descriptor, then // prints enums contained at the top level in descriptor. -void Generator::PrintNestedEnums(const Descriptor& descriptor) const { +void Generator::PrintNestedEnums(const Descriptor& descriptor, + const DescriptorProto& proto) const { for (int i = 0; i < descriptor.nested_type_count(); ++i) { - PrintNestedEnums(*descriptor.nested_type(i)); + PrintNestedEnums(*descriptor.nested_type(i), proto.nested_type(i)); } for (int i = 0; i < descriptor.enum_type_count(); ++i) { - PrintEnum(*descriptor.enum_type(i)); + PrintEnum(*descriptor.enum_type(i), proto.enum_type(i)); } } // Prints Python equivalents of all Descriptors in |file|. void Generator::PrintMessageDescriptors() const { for (int i = 0; i < file_->message_type_count(); ++i) { - PrintDescriptor(*file_->message_type(i)); + PrintDescriptor(*file_->message_type(i), proto_.message_type(i)); printer_->Print("\n"); } } @@ -623,13 +746,14 @@ void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const { // to a Python Descriptor object for message_descriptor. // // Mutually recursive with PrintNestedDescriptors(). -void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { +void Generator::PrintDescriptor(const Descriptor& message_descriptor, + const DescriptorProto& proto) const { absl::flat_hash_map m; m["name"] = message_descriptor.name(); m["full_name"] = message_descriptor.full_name(); m["file"] = kDescriptorKey; - PrintNestedDescriptors(message_descriptor); + PrintNestedDescriptors(message_descriptor, proto); printer_->Print("\n"); printer_->Print("$descriptor_name$ = _descriptor.Descriptor(\n", @@ -644,8 +768,8 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { "containing_type=None,\n" "create_key=_descriptor._internal_create_key,\n"; printer_->Print(m, required_function_arguments); - PrintFieldsInDescriptor(message_descriptor); - PrintExtensionsInDescriptor(message_descriptor); + PrintFieldsInDescriptor(message_descriptor, proto); + PrintExtensionsInDescriptor(message_descriptor, proto); // Nested types printer_->Print("nested_types=["); @@ -668,17 +792,12 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { printer_->Outdent(); printer_->Print("],\n"); std::string options_string; - StripLocalSourceRetentionOptions(message_descriptor) - .SerializeToString(&options_string); + proto.options().SerializeToString(&options_string); printer_->Print( "serialized_options=$options_value$,\n" - "is_extendable=$extendable$,\n" - "syntax='$syntax$'", + "is_extendable=$extendable$", "options_value", OptionsValue(options_string), "extendable", - message_descriptor.extension_range_count() > 0 ? "True" : "False", - "syntax", - StringifySyntax( - FileDescriptorLegacy(message_descriptor.file()).syntax())); + message_descriptor.extension_range_count() > 0 ? "True" : "False"); printer_->Print(",\n"); // Extension ranges @@ -699,8 +818,8 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { m["name"] = desc->name(); m["full_name"] = desc->full_name(); m["index"] = absl::StrCat(desc->index()); - options_string = OptionsValue( - StripLocalSourceRetentionOptions(*desc).SerializeAsString()); + options_string = + OptionsValue(proto.oneof_decl(i).options().SerializeAsString()); if (options_string == "None") { m["serialized_options"] = ""; } else { @@ -725,10 +844,11 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const { // message_descriptor. // // Mutually recursive with PrintDescriptor(). -void Generator::PrintNestedDescriptors( - const Descriptor& containing_descriptor) const { +void Generator::PrintNestedDescriptors(const Descriptor& containing_descriptor, + const DescriptorProto& proto) const { for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) { - PrintDescriptor(*containing_descriptor.nested_type(i)); + PrintDescriptor(*containing_descriptor.nested_type(i), + proto.nested_type(i)); } } @@ -995,12 +1115,12 @@ void Generator::FixForeignFieldsInDescriptors() const { // Returns a Python expression that instantiates a Python EnumValueDescriptor // object for the given C++ descriptor. void Generator::PrintEnumValueDescriptor( - const EnumValueDescriptor& descriptor) const { + const EnumValueDescriptor& descriptor, + const EnumValueDescriptorProto& proto) const { // TODO: Fix up EnumValueDescriptor "type" fields. // More circular references. ::sigh:: std::string options_string; - StripLocalSourceRetentionOptions(descriptor) - .SerializeToString(&options_string); + proto.options().SerializeToString(&options_string); absl::flat_hash_map m; m["name"] = descriptor.name(); m["index"] = absl::StrCat(descriptor.index()); @@ -1014,21 +1134,11 @@ void Generator::PrintEnumValueDescriptor( " create_key=_descriptor._internal_create_key)"); } -// Returns a CEscaped string of serialized_options. -std::string Generator::OptionsValue( - absl::string_view serialized_options) const { - if (serialized_options.length() == 0) { - return "None"; - } else { - return absl::StrCat("b'", absl::CEscape(serialized_options), "'"); - } -} - // Prints an expression for a Python FieldDescriptor for |field|. void Generator::PrintFieldDescriptor(const FieldDescriptor& field, - bool is_extension) const { + const FieldDescriptorProto& proto) const { std::string options_string; - StripLocalSourceRetentionOptions(field).SerializeToString(&options_string); + proto.options().SerializeToString(&options_string); absl::flat_hash_map m; m["name"] = field.name(); m["full_name"] = field.full_name(); @@ -1039,7 +1149,7 @@ void Generator::PrintFieldDescriptor(const FieldDescriptor& field, m["label"] = absl::StrCat(field.label()); m["has_default_value"] = field.has_default_value() ? "True" : "False"; m["default_value"] = StringifyDefaultValue(field); - m["is_extension"] = is_extension ? "True" : "False"; + m["is_extension"] = field.is_extension() ? "True" : "False"; m["serialized_options"] = OptionsValue(options_string); m["json_name"] = field.has_json_name() ? absl::StrCat(", json_name='", field.json_name(), "'") @@ -1062,13 +1172,16 @@ void Generator::PrintFieldDescriptor(const FieldDescriptor& field, // Helper for Print{Fields,Extensions}InDescriptor(). void Generator::PrintFieldDescriptorsInDescriptor( - const Descriptor& message_descriptor, bool is_extension, - absl::string_view list_variable_name, int (Descriptor::*CountFn)() const, - const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const { + const Descriptor& message_descriptor, const DescriptorProto& proto, + bool is_extension, absl::string_view list_variable_name) const { printer_->Print("$list$=[\n", "list", list_variable_name); printer_->Indent(); - for (int i = 0; i < (message_descriptor.*CountFn)(); ++i) { - PrintFieldDescriptor(*(message_descriptor.*GetterFn)(i), is_extension); + int count = is_extension ? message_descriptor.extension_count() + : message_descriptor.field_count(); + for (int i = 0; i < count; ++i) { + PrintFieldDescriptor(is_extension ? *message_descriptor.extension(i) + : *message_descriptor.field(i), + is_extension ? proto.extension(i) : proto.field(i)); printer_->Print(",\n"); } printer_->Outdent(); @@ -1077,22 +1190,20 @@ void Generator::PrintFieldDescriptorsInDescriptor( // Prints a statement assigning "fields" to a list of Python FieldDescriptors, // one for each field present in message_descriptor. -void Generator::PrintFieldsInDescriptor( - const Descriptor& message_descriptor) const { +void Generator::PrintFieldsInDescriptor(const Descriptor& message_descriptor, + const DescriptorProto& proto) const { const bool is_extension = false; - PrintFieldDescriptorsInDescriptor(message_descriptor, is_extension, "fields", - &Descriptor::field_count, - &Descriptor::field); + PrintFieldDescriptorsInDescriptor(message_descriptor, proto, is_extension, + "fields"); } // Prints a statement assigning "extensions" to a list of Python // FieldDescriptors, one for each extension present in message_descriptor. void Generator::PrintExtensionsInDescriptor( - const Descriptor& message_descriptor) const { + const Descriptor& message_descriptor, const DescriptorProto& proto) const { const bool is_extension = true; - PrintFieldDescriptorsInDescriptor(message_descriptor, is_extension, - "extensions", &Descriptor::extension_count, - &Descriptor::extension); + PrintFieldDescriptorsInDescriptor(message_descriptor, proto, is_extension, + "extensions"); } bool Generator::GeneratingDescriptorProto() const { @@ -1167,7 +1278,7 @@ void Generator::PrintSerializedPbInterval( const DescriptorProtoT& descriptor_proto, absl::string_view name) const { std::string sp; descriptor_proto.SerializeToString(&sp); - int offset = file_descriptor_serialized_.find(sp); + size_t offset = file_descriptor_serialized_.find(sp); ABSL_CHECK_GE(offset, 0); printer_->Print( @@ -1177,26 +1288,34 @@ void Generator::PrintSerializedPbInterval( absl::StrCat(offset + sp.size())); } -namespace { -void PrintDescriptorOptionsFixingCode(absl::string_view descriptor, - absl::string_view options, - io::Printer* printer) { +template +bool Generator::PrintDescriptorOptionsFixingCode( + const DescriptorT& descriptor, const typename DescriptorT::Proto& proto, + absl::string_view descriptor_str) const { + std::string options = OptionsValue(proto.options().SerializeAsString()); + // Reset the _options to None thus DescriptorBase.GetOptions() can // parse _options again after extensions are registered. - size_t dot_pos = descriptor.find('.'); + size_t dot_pos = descriptor_str.find('.'); std::string descriptor_name; if (dot_pos == std::string::npos) { - descriptor_name = absl::StrCat("_globals['", descriptor, "']"); + descriptor_name = absl::StrCat("_globals['", descriptor_str, "']"); } else { - descriptor_name = absl::StrCat("_globals['", descriptor.substr(0, dot_pos), - "']", descriptor.substr(dot_pos)); + descriptor_name = + absl::StrCat("_globals['", descriptor_str.substr(0, dot_pos), "']", + descriptor_str.substr(dot_pos)); } - printer->Print( - "$descriptor_name$._options = None\n" + + if (options == "None") { + return false; + } + + printer_->Print( + "$descriptor_name$._loaded_options = None\n" "$descriptor_name$._serialized_options = $serialized_value$\n", "descriptor_name", descriptor_name, "serialized_value", options); + return true; } -} // namespace // Generates the start and end offsets for each entity in the serialized file // descriptor. The file argument must exactly match what was serialized into @@ -1246,148 +1365,117 @@ void Generator::SetMessagePbInterval(const DescriptorProto& message_proto, // Prints expressions that set the options field of all descriptors. void Generator::FixAllDescriptorOptions() const { // Prints an expression that sets the file descriptor's options. - std::string file_options = OptionsValue( - StripLocalSourceRetentionOptions(*file_).SerializeAsString()); - if (file_options != "None") { - PrintDescriptorOptionsFixingCode(kDescriptorKey, file_options, printer_); - } else { - printer_->Print("DESCRIPTOR._options = None\n"); + if (!PrintDescriptorOptionsFixingCode(*file_, proto_, kDescriptorKey)) { + printer_->Print("DESCRIPTOR._loaded_options = None\n"); } // Prints expressions that set the options for all top level enums. for (int i = 0; i < file_->enum_type_count(); ++i) { - const EnumDescriptor& enum_descriptor = *file_->enum_type(i); - FixOptionsForEnum(enum_descriptor); + FixOptionsForEnum(*file_->enum_type(i), proto_.enum_type(i)); } // Prints expressions that set the options for all top level extensions. for (int i = 0; i < file_->extension_count(); ++i) { - const FieldDescriptor& field = *file_->extension(i); - FixOptionsForField(field); + FixOptionsForField(*file_->extension(i), proto_.extension(i)); } // Prints expressions that set the options for all messages, nested enums, // nested extensions and message fields. for (int i = 0; i < file_->message_type_count(); ++i) { - FixOptionsForMessage(*file_->message_type(i)); + FixOptionsForMessage(*file_->message_type(i), proto_.message_type(i)); } for (int i = 0; i < file_->service_count(); ++i) { - FixOptionsForService(*file_->service(i)); + FixOptionsForService(*file_->service(i), proto_.service(i)); } } -void Generator::FixOptionsForOneof(const OneofDescriptor& oneof) const { - std::string oneof_options = - OptionsValue(StripLocalSourceRetentionOptions(oneof).SerializeAsString()); - if (oneof_options != "None") { - std::string oneof_name = absl::Substitute( - "$0.$1['$2']", ModuleLevelDescriptorName(*oneof.containing_type()), - "oneofs_by_name", oneof.name()); - PrintDescriptorOptionsFixingCode(oneof_name, oneof_options, printer_); - } +void Generator::FixOptionsForOneof(const OneofDescriptor& oneof, + const OneofDescriptorProto& proto) const { + std::string oneof_name = absl::Substitute( + "$0.$1['$2']", ModuleLevelDescriptorName(*oneof.containing_type()), + "oneofs_by_name", oneof.name()); + PrintDescriptorOptionsFixingCode(oneof, proto, oneof_name); } // Prints expressions that set the options for an enum descriptor and its // value descriptors. -void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const { +void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor, + const EnumDescriptorProto& proto) const { std::string descriptor_name = ModuleLevelDescriptorName(enum_descriptor); - std::string enum_options = OptionsValue( - StripLocalSourceRetentionOptions(enum_descriptor).SerializeAsString()); - if (enum_options != "None") { - PrintDescriptorOptionsFixingCode(descriptor_name, enum_options, printer_); - } + PrintDescriptorOptionsFixingCode(enum_descriptor, proto, descriptor_name); for (int i = 0; i < enum_descriptor.value_count(); ++i) { const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(i); - std::string value_options = OptionsValue( - StripLocalSourceRetentionOptions(value_descriptor).SerializeAsString()); - if (value_options != "None") { - PrintDescriptorOptionsFixingCode( - absl::StrFormat("%s.values_by_name[\"%s\"]", descriptor_name.c_str(), - value_descriptor.name().c_str()), - value_options, printer_); - } + PrintDescriptorOptionsFixingCode( + value_descriptor, proto.value(i), + absl::StrFormat("%s.values_by_name[\"%s\"]", descriptor_name.c_str(), + value_descriptor.name().c_str())); } } // Prints expressions that set the options for an service descriptor and its // value descriptors. void Generator::FixOptionsForService( - const ServiceDescriptor& service_descriptor) const { + const ServiceDescriptor& service_descriptor, + const ServiceDescriptorProto& proto) const { std::string descriptor_name = ModuleLevelServiceDescriptorName(service_descriptor); - std::string service_options = OptionsValue( - StripLocalSourceRetentionOptions(service_descriptor).SerializeAsString()); - if (service_options != "None") { - PrintDescriptorOptionsFixingCode(descriptor_name, service_options, - printer_); - } + PrintDescriptorOptionsFixingCode(service_descriptor, proto, descriptor_name); for (int i = 0; i < service_descriptor.method_count(); ++i) { const MethodDescriptor* method = service_descriptor.method(i); - std::string method_options = OptionsValue( - StripLocalSourceRetentionOptions(*method).SerializeAsString()); - if (method_options != "None") { - std::string method_name = absl::StrCat( - descriptor_name, ".methods_by_name['", method->name(), "']"); - PrintDescriptorOptionsFixingCode(method_name, method_options, printer_); - } + std::string method_name = absl::StrCat( + descriptor_name, ".methods_by_name['", method->name(), "']"); + PrintDescriptorOptionsFixingCode(*method, proto.method(i), method_name); } } // Prints expressions that set the options for field descriptors (including // extensions). -void Generator::FixOptionsForField(const FieldDescriptor& field) const { - std::string field_options = - OptionsValue(StripLocalSourceRetentionOptions(field).SerializeAsString()); - if (field_options != "None") { - std::string field_name; - if (field.is_extension()) { - if (field.extension_scope() == nullptr) { - // Top level extensions. - field_name = field.name(); - } else { - field_name = FieldReferencingExpression(field.extension_scope(), field, - "extensions_by_name"); - } +void Generator::FixOptionsForField(const FieldDescriptor& field, + const FieldDescriptorProto& proto) const { + std::string field_name; + if (field.is_extension()) { + if (field.extension_scope() == nullptr) { + // Top level extensions. + field_name = field.name(); } else { - field_name = FieldReferencingExpression(field.containing_type(), field, - "fields_by_name"); + field_name = FieldReferencingExpression(field.extension_scope(), field, + "extensions_by_name"); } - PrintDescriptorOptionsFixingCode(field_name, field_options, printer_); + } else { + field_name = FieldReferencingExpression(field.containing_type(), field, + "fields_by_name"); } + PrintDescriptorOptionsFixingCode(field, proto, field_name); } // Prints expressions that set the options for a message and all its inner // types (nested messages, nested enums, extensions, fields). -void Generator::FixOptionsForMessage(const Descriptor& descriptor) const { +void Generator::FixOptionsForMessage(const Descriptor& descriptor, + const DescriptorProto& proto) const { // Nested messages. for (int i = 0; i < descriptor.nested_type_count(); ++i) { - FixOptionsForMessage(*descriptor.nested_type(i)); + FixOptionsForMessage(*descriptor.nested_type(i), proto.nested_type(i)); } // Oneofs. for (int i = 0; i < descriptor.oneof_decl_count(); ++i) { - FixOptionsForOneof(*descriptor.oneof_decl(i)); + FixOptionsForOneof(*descriptor.oneof_decl(i), proto.oneof_decl(i)); } // Enums. for (int i = 0; i < descriptor.enum_type_count(); ++i) { - FixOptionsForEnum(*descriptor.enum_type(i)); + FixOptionsForEnum(*descriptor.enum_type(i), proto.enum_type(i)); } // Fields. for (int i = 0; i < descriptor.field_count(); ++i) { const FieldDescriptor& field = *descriptor.field(i); - FixOptionsForField(field); + FixOptionsForField(field, proto.field(i)); } // Extensions. for (int i = 0; i < descriptor.extension_count(); ++i) { const FieldDescriptor& field = *descriptor.extension(i); - FixOptionsForField(field); + FixOptionsForField(field, proto.extension(i)); } // Message option for this message. - std::string message_options = OptionsValue( - StripLocalSourceRetentionOptions(descriptor).SerializeAsString()); - if (message_options != "None") { - std::string descriptor_name = ModuleLevelDescriptorName(descriptor); - PrintDescriptorOptionsFixingCode(descriptor_name, message_options, - printer_); - } + PrintDescriptorOptionsFixingCode(descriptor, proto, + ModuleLevelDescriptorName(descriptor)); } // If a dependency forwards other files through public dependencies, let's diff --git a/src/google/protobuf/compiler/python/generator.h b/src/google/protobuf/compiler/python/generator.h index 2c73140d9c..bed2dc80cd 100644 --- a/src/google/protobuf/compiler/python/generator.h +++ b/src/google/protobuf/compiler/python/generator.h @@ -12,6 +12,7 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ #define GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__ +#include #include #include @@ -49,6 +50,7 @@ struct GeneratorOptions { bool generate_pyi = false; bool annotate_pyi = false; bool bootstrap = false; + bool strip_nonfunctional_codegen = false; }; class PROTOC_EXPORT Generator : public CodeGenerator { @@ -63,7 +65,15 @@ class PROTOC_EXPORT Generator : public CodeGenerator { GeneratorContext* generator_context, std::string* error) const override; - uint64_t GetSupportedFeatures() const override; + uint64_t GetSupportedFeatures() const override { + return Feature::FEATURE_PROTO3_OPTIONAL | + Feature::FEATURE_SUPPORTS_EDITIONS; + } + Edition GetMinimumEdition() const override { return Edition::EDITION_PROTO2; } + Edition GetMaximumEdition() const override { return Edition::EDITION_2023; } + std::vector GetFeatureExtensions() const override { + return {}; + } void set_opensource_runtime(bool opensource) { opensource_runtime_ = opensource; @@ -73,22 +83,30 @@ class PROTOC_EXPORT Generator : public CodeGenerator { GeneratorOptions ParseParameter(absl::string_view parameter, std::string* error) const; void PrintImports() const; + template + std::string GetResolvedFeatures(const DescriptorT& descriptor) const; + void PrintResolvedFeatures() const; void PrintFileDescriptor() const; void PrintAllEnumsInFile() const; - void PrintNestedEnums(const Descriptor& descriptor) const; - void PrintEnum(const EnumDescriptor& enum_descriptor) const; + void PrintNestedEnums(const Descriptor& descriptor, + const DescriptorProto& proto) const; + void PrintEnum(const EnumDescriptor& enum_descriptor, + const EnumDescriptorProto& proto) const; void PrintFieldDescriptor(const FieldDescriptor& field, - bool is_extension) const; + const FieldDescriptorProto& proto) const; void PrintFieldDescriptorsInDescriptor( - const Descriptor& message_descriptor, bool is_extension, - absl::string_view list_variable_name, int (Descriptor::*CountFn)() const, - const FieldDescriptor* (Descriptor::*GetterFn)(int) const) const; - void PrintFieldsInDescriptor(const Descriptor& message_descriptor) const; - void PrintExtensionsInDescriptor(const Descriptor& message_descriptor) const; + const Descriptor& message_descriptor, const DescriptorProto& proto, + bool is_extension, absl::string_view list_variable_name) const; + void PrintFieldsInDescriptor(const Descriptor& message_descriptor, + const DescriptorProto& proto) const; + void PrintExtensionsInDescriptor(const Descriptor& message_descriptor, + const DescriptorProto& proto) const; void PrintMessageDescriptors() const; - void PrintDescriptor(const Descriptor& message_descriptor) const; - void PrintNestedDescriptors(const Descriptor& containing_descriptor) const; + void PrintDescriptor(const Descriptor& message_descriptor, + const DescriptorProto& proto) const; + void PrintNestedDescriptors(const Descriptor& containing_descriptor, + const DescriptorProto& proto) const; void PrintMessages() const; void PrintMessage(const Descriptor& message_descriptor, @@ -127,8 +145,8 @@ class PROTOC_EXPORT Generator : public CodeGenerator { void PrintDescriptorKeyAndModuleName( const ServiceDescriptor& descriptor) const; - void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor) const; - std::string OptionsValue(absl::string_view serialized_options) const; + void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor, + const EnumValueDescriptorProto& proto) const; bool GeneratingDescriptorProto() const; template @@ -141,12 +159,22 @@ class PROTOC_EXPORT Generator : public CodeGenerator { void PrintSerializedPbInterval(const DescriptorProtoT& descriptor_proto, absl::string_view name) const; + template + bool PrintDescriptorOptionsFixingCode( + const DescriptorT& descriptor, const typename DescriptorT::Proto& proto, + absl::string_view descriptor_str) const; + void FixAllDescriptorOptions() const; - void FixOptionsForField(const FieldDescriptor& field) const; - void FixOptionsForOneof(const OneofDescriptor& oneof) const; - void FixOptionsForEnum(const EnumDescriptor& descriptor) const; - void FixOptionsForService(const ServiceDescriptor& descriptor) const; - void FixOptionsForMessage(const Descriptor& descriptor) const; + void FixOptionsForField(const FieldDescriptor& field, + const FieldDescriptorProto& proto) const; + void FixOptionsForOneof(const OneofDescriptor& oneof, + const OneofDescriptorProto& proto) const; + void FixOptionsForEnum(const EnumDescriptor& descriptor, + const EnumDescriptorProto& proto) const; + void FixOptionsForService(const ServiceDescriptor& descriptor, + const ServiceDescriptorProto& proto) const; + void FixOptionsForMessage(const Descriptor& descriptor, + const DescriptorProto& proto) const; void SetSerializedPbInterval(const FileDescriptorProto& file) const; void SetMessagePbInterval(const DescriptorProto& message_proto, @@ -159,6 +187,7 @@ class PROTOC_EXPORT Generator : public CodeGenerator { // Guards file_, printer_ and file_descriptor_serialized_. mutable absl::Mutex mutex_; mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_. + mutable FileDescriptorProto proto_; // Set in Generate(). Under mutex_. mutable std::string file_descriptor_serialized_; mutable io::Printer* printer_; // Set in Generate(). Under mutex_. diff --git a/src/google/protobuf/compiler/python/pyi_generator.cc b/src/google/protobuf/compiler/python/pyi_generator.cc index 35a4e4ec2d..7f7bfeda08 100644 --- a/src/google/protobuf/compiler/python/pyi_generator.cc +++ b/src/google/protobuf/compiler/python/pyi_generator.cc @@ -18,6 +18,7 @@ #include "absl/strings/match.h" #include "absl/strings/str_split.h" #include "absl/strings/string_view.h" +#include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/compiler/python/helpers.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" @@ -169,6 +170,9 @@ void PyiGenerator::PrintImports() const { bool has_importlib = false; for (int i = 0; i < file_->dependency_count(); ++i) { const FileDescriptor* dep = file_->dependency(i); + if (strip_nonfunctional_codegen_ && IsKnownFeatureProto(dep->name())) { + continue; + } PrintImportForDescriptor(*dep, &seen_aliases, &has_importlib); for (int j = 0; j < dep->public_dependency_count(); ++j) { PrintImportForDescriptor(*dep->public_dependency(j), &seen_aliases, @@ -570,11 +574,14 @@ bool PyiGenerator::Generate(const FileDescriptor* file, std::string filename; bool annotate_code = false; + strip_nonfunctional_codegen_ = false; for (const std::pair& option : options) { if (option.first == "annotate_code") { annotate_code = true; } else if (absl::EndsWith(option.first, ".pyi")) { filename = option.first; + } else if (option.first == "experimental_strip_nonfunctional_codegen") { + strip_nonfunctional_codegen_ = true; } else { *error = absl::StrCat("Unknown generator option: ", option.first); return false; diff --git a/src/google/protobuf/compiler/python/pyi_generator.h b/src/google/protobuf/compiler/python/pyi_generator.h index 84c802bee8..a015880b8e 100644 --- a/src/google/protobuf/compiler/python/pyi_generator.h +++ b/src/google/protobuf/compiler/python/pyi_generator.h @@ -13,6 +13,7 @@ #define GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__ #include +#include #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" @@ -47,12 +48,19 @@ class PROTOC_EXPORT PyiGenerator : public google::protobuf::compiler::CodeGenera // CodeGenerator methods. uint64_t GetSupportedFeatures() const override { // Code generators must explicitly support proto3 optional. - return CodeGenerator::FEATURE_PROTO3_OPTIONAL; + return Feature::FEATURE_PROTO3_OPTIONAL | + Feature::FEATURE_SUPPORTS_EDITIONS; } bool Generate(const FileDescriptor* file, const std::string& parameter, GeneratorContext* generator_context, std::string* error) const override; + Edition GetMinimumEdition() const override { return Edition::EDITION_PROTO2; } + Edition GetMaximumEdition() const override { return Edition::EDITION_2023; } + std::vector GetFeatureExtensions() const override { + return {}; + } + private: void PrintImportForDescriptor(const FileDescriptor& desc, absl::flat_hash_set* seen_aliases, @@ -83,6 +91,7 @@ class PROTOC_EXPORT PyiGenerator : public google::protobuf::compiler::CodeGenera mutable absl::Mutex mutex_; mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_. mutable io::Printer* printer_; // Set in Generate(). Under mutex_. + mutable bool strip_nonfunctional_codegen_ = false; // Set in Generate(). // import_map will be a mapping from filename to module alias, e.g. // "google3/foo/bar.py" -> "_bar" mutable absl::flat_hash_map import_map_; diff --git a/src/google/protobuf/compiler/ruby/BUILD.bazel b/src/google/protobuf/compiler/ruby/BUILD.bazel index 62afc3c35a..9e921542fc 100644 --- a/src/google/protobuf/compiler/ruby/BUILD.bazel +++ b/src/google/protobuf/compiler/ruby/BUILD.bazel @@ -17,7 +17,6 @@ cc_library( "//src/google/protobuf/compiler:__pkg__", ], deps = [ - "//src/google/protobuf:descriptor_legacy", "//src/google/protobuf:protobuf_nowkt", "//src/google/protobuf/compiler:code_generator", "//src/google/protobuf/compiler:retention", diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc index 7bc8283371..1d85046b24 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc @@ -19,7 +19,6 @@ #include "google/protobuf/compiler/retention.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" -#include "google/protobuf/descriptor_legacy.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/io/zero_copy_stream.h" @@ -40,7 +39,7 @@ void GenerateEnumAssignment(absl::string_view prefix, const EnumDescriptor* en, io::Printer* printer); std::string DefaultValueForField(const FieldDescriptor* field); -template +template std::string NumberToString(numeric_type value) { std::ostringstream os; os << value; @@ -65,7 +64,6 @@ bool IsAlpha(char ch) { return IsLower(ch) || IsUpper(ch); } char UpperChar(char ch) { return IsLower(ch) ? (ch - 'a' + 'A') : ch; } - // Package names in protobuf are snake_case by convention, but Ruby module // names must be PascalCased. // @@ -123,14 +121,12 @@ void GenerateMessageAssignment(absl::string_view prefix, return; } + printer->Print("$prefix$$name$ = ", "prefix", prefix, "name", + RubifyConstant(message->name())); printer->Print( - "$prefix$$name$ = ", - "prefix", prefix, - "name", RubifyConstant(message->name())); - printer->Print( - "::Google::Protobuf::DescriptorPool.generated_pool." - "lookup(\"$full_name$\").msgclass\n", - "full_name", message->full_name()); + "::Google::Protobuf::DescriptorPool.generated_pool." + "lookup(\"$full_name$\").msgclass\n", + "full_name", message->full_name()); std::string nested_prefix = absl::StrCat(prefix, RubifyConstant(message->name()), "::"); @@ -144,14 +140,12 @@ void GenerateMessageAssignment(absl::string_view prefix, void GenerateEnumAssignment(absl::string_view prefix, const EnumDescriptor* en, io::Printer* printer) { + printer->Print("$prefix$$name$ = ", "prefix", prefix, "name", + RubifyConstant(en->name())); printer->Print( - "$prefix$$name$ = ", - "prefix", prefix, - "name", RubifyConstant(en->name())); - printer->Print( - "::Google::Protobuf::DescriptorPool.generated_pool." - "lookup(\"$full_name$\").enummodule\n", - "full_name", en->full_name()); + "::Google::Protobuf::DescriptorPool.generated_pool." + "lookup(\"$full_name$\").enummodule\n", + "full_name", en->full_name()); } int GeneratePackageModules(const FileDescriptor* file, io::Printer* printer) { @@ -197,9 +191,7 @@ int GeneratePackageModules(const FileDescriptor* file, io::Printer* printer) { if (need_change_to_module) { component = PackageToModule(component); } - printer->Print( - "module $name$\n", - "name", component); + printer->Print("module $name$\n", "name", component); printer->Indent(); levels++; } @@ -210,8 +202,7 @@ void EndPackageModules(int levels, io::Printer* printer) { while (levels > 0) { levels--; printer->Outdent(); - printer->Print( - "end\n"); + printer->Print("end\n"); } } @@ -304,16 +295,12 @@ bool GenerateFile(const FileDescriptor* file, io::Printer* printer, if (file->dependency_count() != 0) { for (int i = 0; i < file->dependency_count(); i++) { - printer->Print("require '$name$'\n", "name", GetRequireName(file->dependency(i)->name())); + printer->Print("require '$name$'\n", "name", + GetRequireName(file->dependency(i)->name())); } printer->Print("\n"); } - // TODO: Remove this when ruby supports extensions. - if (file->extension_count() > 0) { - ABSL_LOG(WARNING) << "Extensions are not yet supported in Ruby."; - } - GenerateBinaryDescriptor(file, printer, error); int levels = GeneratePackageModules(file, printer); @@ -328,17 +315,10 @@ bool GenerateFile(const FileDescriptor* file, io::Printer* printer, return true; } -bool Generator::Generate( - const FileDescriptor* file, - const std::string& parameter, - GeneratorContext* generator_context, - std::string* error) const { - if (FileDescriptorLegacy(file).syntax() == - FileDescriptorLegacy::Syntax::SYNTAX_UNKNOWN) { - *error = "Invalid or unsupported proto syntax"; - return false; - } - +bool Generator::Generate(const FileDescriptor* file, + const std::string& parameter, + GeneratorContext* generator_context, + std::string* error) const { std::unique_ptr output( generator_context->Open(GetOutputFilename(file->name()))); io::Printer printer(output.get(), '$'); diff --git a/src/google/protobuf/compiler/rust/BUILD.bazel b/src/google/protobuf/compiler/rust/BUILD.bazel index 9939c2ca21..e9639700a1 100644 --- a/src/google/protobuf/compiler/rust/BUILD.bazel +++ b/src/google/protobuf/compiler/rust/BUILD.bazel @@ -51,6 +51,7 @@ cc_library( name = "accessors", srcs = [ "accessors/accessors.cc", + "accessors/map.cc", "accessors/repeated_scalar.cc", "accessors/singular_message.cc", "accessors/singular_scalar.cc", @@ -65,6 +66,7 @@ cc_library( strip_include_prefix = "/src", deps = [ ":context", + ":helpers", ":naming", "//src/google/protobuf:protobuf_nowkt", "//src/google/protobuf/compiler/cpp:names_internal", @@ -141,3 +143,16 @@ cc_test( "@com_google_googletest//:gtest_main", ], ) + +cc_library( + name = "helpers", + srcs = ["accessors/helpers.cc"], + hdrs = ["accessors/helpers.h"], + strip_include_prefix = "/src", + deps = [ + ":context", + "//src/google/protobuf:protobuf_nowkt", + "@com_google_absl//absl/log:absl_check", + "@com_google_absl//absl/strings", + ], +) diff --git a/src/google/protobuf/compiler/rust/accessors/accessor_generator.h b/src/google/protobuf/compiler/rust/accessors/accessor_generator.h index 3bf1dca06d..442de3c7cc 100644 --- a/src/google/protobuf/compiler/rust/accessors/accessor_generator.h +++ b/src/google/protobuf/compiler/rust/accessors/accessor_generator.h @@ -9,6 +9,8 @@ #define GOOGLE_PROTOBUF_COMPILER_RUST_ACCESSORS_ACCESSOR_GENERATOR_H__ #include +#include +#include #include "absl/log/absl_check.h" #include "google/protobuf/compiler/rust/context.h" @@ -96,8 +98,20 @@ class RepeatedScalar final : public AccessorGenerator { class UnsupportedField final : public AccessorGenerator { public: + explicit UnsupportedField(std::string reason) : reason_(std::move(reason)) {} ~UnsupportedField() override = default; void InMsgImpl(Context field) const override; + + private: + std::string reason_; +}; + +class Map final : public AccessorGenerator { + public: + ~Map() override = default; + void InMsgImpl(Context field) const override; + void InExternC(Context field) const override; + void InThunkCc(Context field) const override; }; } // namespace rust diff --git a/src/google/protobuf/compiler/rust/accessors/accessors.cc b/src/google/protobuf/compiler/rust/accessors/accessors.cc index fa5c876bf9..c25fbc207f 100644 --- a/src/google/protobuf/compiler/rust/accessors/accessors.cc +++ b/src/google/protobuf/compiler/rust/accessors/accessors.cc @@ -9,6 +9,7 @@ #include +#include "absl/log/absl_log.h" #include "google/protobuf/compiler/rust/accessors/accessor_generator.h" #include "google/protobuf/compiler/rust/context.h" #include "google/protobuf/descriptor.h" @@ -22,11 +23,27 @@ namespace rust { namespace { std::unique_ptr AccessorGeneratorFor( - const FieldDescriptor& desc) { - // We do not support [ctype=FOO] (used to set the field type in C++ to - // cord or string_piece) in V0 API. + Context field) { + const FieldDescriptor& desc = field.desc(); + // TODO: We do not support [ctype=FOO] (used to set the field + // type in C++ to cord or string_piece) in V0.6 API. if (desc.options().has_ctype()) { - return std::make_unique(); + return std::make_unique( + "fields with ctype not supported"); + } + + if (desc.is_map()) { + auto value_type = desc.message_type()->map_value()->type(); + switch (value_type) { + case FieldDescriptor::TYPE_BYTES: + case FieldDescriptor::TYPE_ENUM: + case FieldDescriptor::TYPE_MESSAGE: + return std::make_unique( + "Maps with values of type bytes, enum and message are not " + "supported"); + default: + return std::make_unique(); + } } switch (desc.type()) { @@ -50,32 +67,43 @@ std::unique_ptr AccessorGeneratorFor( case FieldDescriptor::TYPE_BYTES: case FieldDescriptor::TYPE_STRING: if (desc.is_repeated()) { - return std::make_unique(); + return std::make_unique("repeated str not supported"); } return std::make_unique(); case FieldDescriptor::TYPE_MESSAGE: if (desc.is_repeated()) { - return std::make_unique(); + return std::make_unique("repeated msg not supported"); + } + if (!field.generator_context().is_file_in_current_crate( + desc.message_type()->file())) { + return std::make_unique( + "message fields that are imported from another proto_library" + " (defined in a separate Rust crate) are not supported"); } return std::make_unique(); - default: - return std::make_unique(); + case FieldDescriptor::TYPE_ENUM: + return std::make_unique("enum not supported"); + + case FieldDescriptor::TYPE_GROUP: + return std::make_unique("group not supported"); } + + ABSL_LOG(FATAL) << "Unexpected field type: " << desc.type(); } } // namespace void GenerateAccessorMsgImpl(Context field) { - AccessorGeneratorFor(field.desc())->GenerateMsgImpl(field); + AccessorGeneratorFor(field)->GenerateMsgImpl(field); } void GenerateAccessorExternC(Context field) { - AccessorGeneratorFor(field.desc())->GenerateExternC(field); + AccessorGeneratorFor(field)->GenerateExternC(field); } void GenerateAccessorThunkCc(Context field) { - AccessorGeneratorFor(field.desc())->GenerateThunkCc(field); + AccessorGeneratorFor(field)->GenerateThunkCc(field); } } // namespace rust diff --git a/src/google/protobuf/compiler/rust/accessors/helpers.cc b/src/google/protobuf/compiler/rust/accessors/helpers.cc new file mode 100644 index 0000000000..b2d2a1bed8 --- /dev/null +++ b/src/google/protobuf/compiler/rust/accessors/helpers.cc @@ -0,0 +1,90 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google LLC. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "google/protobuf/compiler/rust/accessors/helpers.h" + +#include +#include +#include + +#include "absl/log/absl_log.h" +#include "absl/strings/escaping.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" +#include "google/protobuf/compiler/rust/context.h" +#include "google/protobuf/descriptor.h" +#include "google/protobuf/io/strtod.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace rust { + +std::string DefaultValue(Context field) { + switch (field.desc().type()) { + case FieldDescriptor::TYPE_DOUBLE: + if (std::isfinite(field.desc().default_value_double())) { + return absl::StrCat(io::SimpleDtoa(field.desc().default_value_double()), + "f64"); + } else if (std::isnan(field.desc().default_value_double())) { + return std::string("f64::NAN"); + } else if (field.desc().default_value_double() == + std::numeric_limits::infinity()) { + return std::string("f64::INFINITY"); + } else if (field.desc().default_value_double() == + -std::numeric_limits::infinity()) { + return std::string("f64::NEG_INFINITY"); + } else { + ABSL_LOG(FATAL) << "unreachable"; + } + case FieldDescriptor::TYPE_FLOAT: + if (std::isfinite(field.desc().default_value_float())) { + return absl::StrCat(io::SimpleFtoa(field.desc().default_value_float()), + "f32"); + } else if (std::isnan(field.desc().default_value_float())) { + return std::string("f32::NAN"); + } else if (field.desc().default_value_float() == + std::numeric_limits::infinity()) { + return std::string("f32::INFINITY"); + } else if (field.desc().default_value_float() == + -std::numeric_limits::infinity()) { + return std::string("f32::NEG_INFINITY"); + } else { + ABSL_LOG(FATAL) << "unreachable"; + } + case FieldDescriptor::TYPE_INT32: + case FieldDescriptor::TYPE_SFIXED32: + case FieldDescriptor::TYPE_SINT32: + return absl::StrFormat("%d", field.desc().default_value_int32()); + case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_SFIXED64: + case FieldDescriptor::TYPE_SINT64: + return absl::StrFormat("%d", field.desc().default_value_int64()); + case FieldDescriptor::TYPE_FIXED64: + case FieldDescriptor::TYPE_UINT64: + return absl::StrFormat("%u", field.desc().default_value_uint64()); + case FieldDescriptor::TYPE_FIXED32: + case FieldDescriptor::TYPE_UINT32: + return absl::StrFormat("%u", field.desc().default_value_uint32()); + case FieldDescriptor::TYPE_BOOL: + return absl::StrFormat("%v", field.desc().default_value_bool()); + case FieldDescriptor::TYPE_STRING: + case FieldDescriptor::TYPE_BYTES: + return absl::StrFormat( + "b\"%s\"", absl::CHexEscape(field.desc().default_value_string())); + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: + case FieldDescriptor::TYPE_ENUM: + ABSL_LOG(FATAL) << "Unsupported field type: " << field.desc().type_name(); + } + ABSL_LOG(FATAL) << "unreachable"; +} + +} // namespace rust +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/rust/accessors/helpers.h b/src/google/protobuf/compiler/rust/accessors/helpers.h new file mode 100644 index 0000000000..45c7f3afa2 --- /dev/null +++ b/src/google/protobuf/compiler/rust/accessors/helpers.h @@ -0,0 +1,33 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google LLC. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#ifndef GOOGLE_PROTOBUF_COMPILER_RUST_ACCESSORS_HELPERS_H__ +#define GOOGLE_PROTOBUF_COMPILER_RUST_ACCESSORS_HELPERS_H__ + +#include + +#include "google/protobuf/compiler/rust/context.h" +#include "google/protobuf/descriptor.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace rust { + +// Returns the field's default value as a Rust literal / identifier. +// +// Both strings and bytes are represented as a byte string literal, i.e. in the +// format `b"default value here"`. It is the caller's responsibility to convert +// the byte literal to an actual string, if needed. +std::string DefaultValue(Context field); + +} // namespace rust +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_RUST_ACCESSORS_HELPERS_H__ diff --git a/src/google/protobuf/compiler/rust/accessors/map.cc b/src/google/protobuf/compiler/rust/accessors/map.cc new file mode 100644 index 0000000000..0c2c1eb29d --- /dev/null +++ b/src/google/protobuf/compiler/rust/accessors/map.cc @@ -0,0 +1,151 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google LLC. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "google/protobuf/compiler/cpp/helpers.h" +#include "google/protobuf/compiler/rust/accessors/accessor_generator.h" +#include "google/protobuf/compiler/rust/context.h" +#include "google/protobuf/compiler/rust/naming.h" +#include "google/protobuf/descriptor.h" +#include "google/protobuf/descriptor.pb.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace rust { + +void Map::InMsgImpl(Context field) const { + auto& key_type = *field.desc().message_type()->map_key(); + auto& value_type = *field.desc().message_type()->map_value(); + + field.Emit({{"field", field.desc().name()}, + {"Key", PrimitiveRsTypeName(key_type)}, + {"Value", PrimitiveRsTypeName(value_type)}, + {"getter_thunk", Thunk(field, "get")}, + {"getter_mut_thunk", Thunk(field, "get_mut")}, + {"getter", + [&] { + if (field.is_upb()) { + field.Emit({}, R"rs( + pub fn r#$field$(&self) + -> $pb$::View<'_, $pb$::Map<$Key$, $Value$>> { + let inner = unsafe { + $getter_thunk$(self.inner.msg) + }.map_or_else(|| unsafe {$pbr$::empty_map()}, |raw| { + $pbr$::MapInner{ + raw, + arena: &self.inner.arena, + _phantom_key: std::marker::PhantomData, + _phantom_value: std::marker::PhantomData, + } + }); + $pb$::MapView::from_inner($pbi$::Private, inner) + })rs"); + } else { + field.Emit({}, R"rs( + pub fn r#$field$(&self) + -> $pb$::View<'_, $pb$::Map<$Key$, $Value$>> { + let inner = $pbr$::MapInner { + raw: unsafe { $getter_thunk$(self.inner.msg) }, + _phantom_key: std::marker::PhantomData, + _phantom_value: std::marker::PhantomData, + }; + $pb$::MapView::from_inner($pbi$::Private, inner) + })rs"); + } + }}, + {"getter_mut", + [&] { + if (field.is_upb()) { + field.Emit({}, R"rs( + pub fn r#$field$_mut(&mut self) + -> $pb$::Mut<'_, $pb$::Map<$Key$, $Value$>> { + let raw = unsafe { + $getter_mut_thunk$(self.inner.msg, + self.inner.arena.raw()) + }; + let inner = $pbr$::MapInner{ + raw, + arena: &self.inner.arena, + _phantom_key: std::marker::PhantomData, + _phantom_value: std::marker::PhantomData, + }; + $pb$::MapMut::from_inner($pbi$::Private, inner) + })rs"); + } else { + field.Emit({}, R"rs( + pub fn r#$field$_mut(&mut self) + -> $pb$::Mut<'_, $pb$::Map<$Key$, $Value$>> { + let inner = $pbr$::MapInner { + raw: unsafe { $getter_mut_thunk$(self.inner.msg) }, + _phantom_key: std::marker::PhantomData, + _phantom_value: std::marker::PhantomData, + }; + $pb$::MapMut::from_inner($pbi$::Private, inner) + })rs"); + } + }}}, + R"rs( + $getter$ + $getter_mut$ + )rs"); +} + +void Map::InExternC(Context field) const { + field.Emit( + { + {"getter_thunk", Thunk(field, "get")}, + {"getter_mut_thunk", Thunk(field, "get_mut")}, + {"getter", + [&] { + if (field.is_upb()) { + field.Emit({}, R"rs( + fn $getter_thunk$(raw_msg: $pbi$::RawMessage) + -> Option<$pbi$::RawMap>; + fn $getter_mut_thunk$(raw_msg: $pbi$::RawMessage, + arena: $pbi$::RawArena) -> $pbi$::RawMap; + )rs"); + } else { + field.Emit({}, R"rs( + fn $getter_thunk$(msg: $pbi$::RawMessage) -> $pbi$::RawMap; + fn $getter_mut_thunk$(msg: $pbi$::RawMessage,) -> $pbi$::RawMap; + )rs"); + } + }}, + }, + R"rs( + $getter$ + )rs"); +} + +void Map::InThunkCc(Context field) const { + field.Emit( + {{"field", cpp::FieldName(&field.desc())}, + {"Key", cpp::PrimitiveTypeName( + field.desc().message_type()->map_key()->cpp_type())}, + {"Value", cpp::PrimitiveTypeName( + field.desc().message_type()->map_value()->cpp_type())}, + {"QualifiedMsg", + cpp::QualifiedClassName(field.desc().containing_type())}, + {"getter_thunk", Thunk(field, "get")}, + {"getter_mut_thunk", Thunk(field, "get_mut")}, + {"impls", + [&] { + field.Emit( + R"cc( + const void* $getter_thunk$($QualifiedMsg$& msg) { + return &msg.$field$(); + } + void* $getter_mut_thunk$($QualifiedMsg$* msg) { return msg->mutable_$field$(); } + )cc"); + }}}, + "$impls$"); +} + +} // namespace rust +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/rust/accessors/singular_message.cc b/src/google/protobuf/compiler/rust/accessors/singular_message.cc index 2978631faf..210512a7eb 100644 --- a/src/google/protobuf/compiler/rust/accessors/singular_message.cc +++ b/src/google/protobuf/compiler/rust/accessors/singular_message.cc @@ -5,7 +5,6 @@ // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd -#include "absl/strings/match.h" #include "absl/strings/string_view.h" #include "google/protobuf/compiler/cpp/helpers.h" #include "google/protobuf/compiler/rust/accessors/accessor_generator.h" @@ -20,49 +19,94 @@ namespace rust { void SingularMessage::InMsgImpl(Context field) const { Context d = field.WithDesc(field.desc().message_type()); + auto prefix = "crate::" + GetCrateRelativeQualifiedPath(d); - // here we defer unit tests with messages that have import inside their - // pkg name e.g. unittest_import.proto - if (absl::StrContains(prefix, "import")) { - // TODO: Handle imports correctly, default to $Msg$View for now - prefix = field.desc().containing_type()->name(); - } - if (field.is_cpp()) { - field.Emit({{"prefix", prefix}, - {"field", field.desc().name()}, - {"getter_thunk", Thunk(field, "get")}}, - R"rs( - pub fn r#$field$(&self) -> $prefix$View { - // For C++ kernel, getters automatically return the - // default_instance if the field is unset. - let submsg = unsafe { $getter_thunk$(self.inner.msg) }; - $prefix$View::new($pbi$::Private, submsg) - } - )rs"); - } else { - field.Emit({{"prefix", prefix}, - {"field", field.desc().name()}, - {"getter_thunk", Thunk(field, "get")}}, - R"rs( - pub fn r#$field$(&self) -> $prefix$View { - let submsg = unsafe { $getter_thunk$(self.inner.msg) }; - // For upb, getters return null if the field is unset, so we need to - // check for null and return the default instance manually. Note that - // a null ptr received from upb manifests as Option::None - match submsg { + + field.Emit( + { + {"prefix", prefix}, + {"field", field.desc().name()}, + {"getter_thunk", Thunk(field, "get")}, + {"getter_mut_thunk", Thunk(field, "get_mut")}, + {"clearer_thunk", Thunk(field, "clear")}, + { + "view_body", + [&] { + if (field.is_upb()) { + field.Emit({}, R"rs( + let submsg = unsafe { $getter_thunk$(self.inner.msg) }; + // For upb, getters return null if the field is unset, so we need + // to check for null and return the default instance manually. + // Note that a nullptr received from upb manifests as Option::None + match submsg { // TODO:(b/304357029) - None => $prefix$View::new($pbi$::Private, $pbr$::ScratchSpace::zeroed_block($pbi$::Private)), + None => $prefix$View::new($pbi$::Private, + $pbr$::ScratchSpace::zeroed_block($pbi$::Private)), Some(field) => $prefix$View::new($pbi$::Private, field), } - } )rs"); - } + } else { + field.Emit({}, R"rs( + // For C++ kernel, getters automatically return the + // default_instance if the field is unset. + let submsg = unsafe { $getter_thunk$(self.inner.msg) }; + $prefix$View::new($pbi$::Private, submsg) + )rs"); + } + }, + }, + {"submessage_mut", + [&] { + if (field.is_upb()) { + field.Emit({}, R"rs( + let submsg = unsafe { + $getter_mut_thunk$(self.inner.msg, self.inner.arena.raw()) + }; + $prefix$Mut::new($pbi$::Private, &mut self.inner, submsg) + )rs"); + } else { + field.Emit({}, R"rs( + let submsg = unsafe { $getter_mut_thunk$(self.inner.msg) }; + $prefix$Mut::new($pbi$::Private, &mut self.inner, submsg) + )rs"); + } + }}, + }, + R"rs( + pub fn r#$field$(&self) -> $prefix$View { + $view_body$ + } + + pub fn $field$_mut(&mut self) -> $prefix$Mut { + $submessage_mut$ + } + + pub fn $field$_clear(&mut self) { + unsafe { $clearer_thunk$(self.inner.msg) } + } + )rs"); } void SingularMessage::InExternC(Context field) const { field.Emit( { {"getter_thunk", Thunk(field, "get")}, + {"getter_mut_thunk", Thunk(field, "get_mut")}, + {"clearer_thunk", Thunk(field, "clear")}, + {"getter_mut", + [&] { + if (field.is_cpp()) { + field.Emit( + R"rs( + fn $getter_mut_thunk$(raw_msg: $pbi$::RawMessage) + -> $pbi$::RawMessage;)rs"); + } else { + field.Emit( + R"rs(fn $getter_mut_thunk$(raw_msg: $pbi$::RawMessage, + arena: $pbi$::RawArena) + -> $pbi$::RawMessage;)rs"); + } + }}, {"ReturnType", [&] { if (field.is_cpp()) { @@ -77,6 +121,8 @@ void SingularMessage::InExternC(Context field) const { }, R"rs( fn $getter_thunk$(raw_msg: $pbi$::RawMessage) -> $ReturnType$; + $getter_mut$ + fn $clearer_thunk$(raw_msg: $pbi$::RawMessage); )rs"); } @@ -84,11 +130,17 @@ void SingularMessage::InThunkCc(Context field) const { field.Emit({{"QualifiedMsg", cpp::QualifiedClassName(field.desc().containing_type())}, {"getter_thunk", Thunk(field, "get")}, + {"getter_mut_thunk", Thunk(field, "get_mut")}, + {"clearer_thunk", Thunk(field, "clear")}, {"field", cpp::FieldName(&field.desc())}}, R"cc( const void* $getter_thunk$($QualifiedMsg$* msg) { return static_cast(&msg->$field$()); } + void* $getter_mut_thunk$($QualifiedMsg$* msg) { + return static_cast(msg->mutable_$field$()); + } + void $clearer_thunk$($QualifiedMsg$* msg) { msg->clear_$field$(); } )cc"); } diff --git a/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc b/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc index b7b7a55643..98593c79d8 100644 --- a/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc +++ b/src/google/protobuf/compiler/rust/accessors/singular_scalar.cc @@ -5,20 +5,13 @@ // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd -#include -#include -#include - -#include "absl/log/absl_log.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_format.h" #include "absl/strings/string_view.h" #include "google/protobuf/compiler/cpp/helpers.h" #include "google/protobuf/compiler/rust/accessors/accessor_generator.h" +#include "google/protobuf/compiler/rust/accessors/helpers.h" #include "google/protobuf/compiler/rust/context.h" #include "google/protobuf/compiler/rust/naming.h" #include "google/protobuf/descriptor.h" -#include "google/protobuf/io/strtod.h" namespace google { namespace protobuf { @@ -31,72 +24,7 @@ void SingularScalar::InMsgImpl(Context field) const { {"field", field.desc().name()}, {"Scalar", PrimitiveRsTypeName(field.desc())}, {"hazzer_thunk", Thunk(field, "has")}, - {"default_value", - [&] { - switch (field.desc().type()) { - case FieldDescriptor::TYPE_DOUBLE: - if (std::isfinite(field.desc().default_value_double())) { - return absl::StrCat( - io::SimpleDtoa(field.desc().default_value_double()), - "f64"); - } else if (std::isnan(field.desc().default_value_double())) { - return std::string("f64::NAN"); - } else if (field.desc().default_value_double() == - std::numeric_limits::infinity()) { - return std::string("f64::INFINITY"); - } else if (field.desc().default_value_double() == - -std::numeric_limits::infinity()) { - return std::string("f64::NEG_INFINITY"); - } else { - ABSL_LOG(FATAL) << "unreachable"; - } - case FieldDescriptor::TYPE_FLOAT: - if (std::isfinite(field.desc().default_value_float())) { - return absl::StrCat( - io::SimpleFtoa(field.desc().default_value_float()), - "f32"); - } else if (std::isnan(field.desc().default_value_float())) { - return std::string("f32::NAN"); - } else if (field.desc().default_value_float() == - std::numeric_limits::infinity()) { - return std::string("f32::INFINITY"); - } else if (field.desc().default_value_float() == - -std::numeric_limits::infinity()) { - return std::string("f32::NEG_INFINITY"); - } else { - ABSL_LOG(FATAL) << "unreachable"; - } - case FieldDescriptor::TYPE_INT32: - case FieldDescriptor::TYPE_SFIXED32: - case FieldDescriptor::TYPE_SINT32: - return absl::StrFormat("%d", - field.desc().default_value_int32()); - case FieldDescriptor::TYPE_INT64: - case FieldDescriptor::TYPE_SFIXED64: - case FieldDescriptor::TYPE_SINT64: - return absl::StrFormat("%d", - field.desc().default_value_int64()); - case FieldDescriptor::TYPE_FIXED64: - case FieldDescriptor::TYPE_UINT64: - return absl::StrFormat("%u", - field.desc().default_value_uint64()); - case FieldDescriptor::TYPE_FIXED32: - case FieldDescriptor::TYPE_UINT32: - return absl::StrFormat("%u", - field.desc().default_value_uint32()); - case FieldDescriptor::TYPE_BOOL: - return absl::StrFormat("%v", - field.desc().default_value_bool()); - case FieldDescriptor::TYPE_STRING: - case FieldDescriptor::TYPE_GROUP: - case FieldDescriptor::TYPE_MESSAGE: - case FieldDescriptor::TYPE_BYTES: - case FieldDescriptor::TYPE_ENUM: - ABSL_LOG(FATAL) << "Non-singular scalar field type passed: " - << field.desc().type_name(); - } - ABSL_LOG(FATAL) << "unreachable"; - }()}, + {"default_value", DefaultValue(field)}, {"getter", [&] { field.Emit({}, R"rs( @@ -133,6 +61,12 @@ void SingularScalar::InMsgImpl(Context field) const { } } )rs"); + } else { + field.Emit({}, R"rs( + pub fn r#$field$_set(&mut self, val: $Scalar$) { + unsafe { $setter_thunk$(self.inner.msg, val) } + } + )rs"); } }}, {"field_mutator_getter", @@ -170,7 +104,7 @@ void SingularScalar::InMsgImpl(Context field) const { $setter_thunk$, ); - $pb$::PrimitiveMut::from_singular( + $pb$::PrimitiveMut::from_inner( $pbi$::Private, unsafe { $pbi$::RawVTableMutator::new( diff --git a/src/google/protobuf/compiler/rust/accessors/singular_string.cc b/src/google/protobuf/compiler/rust/accessors/singular_string.cc index 2ba36f6a7d..f3ae1e2f49 100644 --- a/src/google/protobuf/compiler/rust/accessors/singular_string.cc +++ b/src/google/protobuf/compiler/rust/accessors/singular_string.cc @@ -7,10 +7,10 @@ #include -#include "absl/strings/escaping.h" #include "absl/strings/string_view.h" #include "google/protobuf/compiler/cpp/helpers.h" #include "google/protobuf/compiler/rust/accessors/accessor_generator.h" +#include "google/protobuf/compiler/rust/accessors/helpers.h" #include "google/protobuf/compiler/rust/context.h" #include "google/protobuf/compiler/rust/naming.h" #include "google/protobuf/descriptor.h" @@ -52,14 +52,12 @@ void SingularString::InMsgImpl(Context field) const { {"transform_view", transform_view}}, R"rs( pub fn $field$_opt(&self) -> $pb$::Optional<&$proxied_type$> { - unsafe { - let view = $getter_thunk$(self.inner.msg).as_ref(); + let view = unsafe { $getter_thunk$(self.inner.msg).as_ref() }; $pb$::Optional::new( $transform_view$ , - $hazzer_thunk$(self.inner.msg) + unsafe { $hazzer_thunk$(self.inner.msg) } ) } - } )rs"); }}, {"field_mutator_getter", @@ -69,8 +67,7 @@ void SingularString::InMsgImpl(Context field) const { { {"field", field.desc().name()}, {"proxied_type", proxied_type}, - {"default_val", - absl::CHexEscape(field.desc().default_value_string())}, + {"default_val", DefaultValue(field)}, {"view_type", proxied_type}, {"transform_field_entry", [&] { @@ -98,7 +95,7 @@ void SingularString::InMsgImpl(Context field) const { $getter_thunk$, $setter_thunk$, $clearer_thunk$, - b"$default_val$", + $default_val$, ) }; let out = unsafe { diff --git a/src/google/protobuf/compiler/rust/accessors/unsupported_field.cc b/src/google/protobuf/compiler/rust/accessors/unsupported_field.cc index ad0a98901c..e6bce02171 100644 --- a/src/google/protobuf/compiler/rust/accessors/unsupported_field.cc +++ b/src/google/protobuf/compiler/rust/accessors/unsupported_field.cc @@ -16,8 +16,8 @@ namespace compiler { namespace rust { void UnsupportedField::InMsgImpl(Context field) const { - field.Emit(R"rs( - // Unsupported! :( + field.Emit({{"reason", reason_}}, R"rs( + // Unsupported! :( Reason: $reason$ )rs"); field.printer().PrintRaw("\n"); } diff --git a/src/google/protobuf/compiler/rust/context.cc b/src/google/protobuf/compiler/rust/context.cc index 82ac86a0c0..68d4c9fb2a 100644 --- a/src/google/protobuf/compiler/rust/context.cc +++ b/src/google/protobuf/compiler/rust/context.cc @@ -17,6 +17,7 @@ #include "absl/strings/string_view.h" #include "absl/strings/substitute.h" #include "google/protobuf/compiler/code_generator.h" +#include "google/protobuf/descriptor.h" namespace google { namespace protobuf { @@ -67,6 +68,15 @@ absl::StatusOr Options::Parse(absl::string_view param) { return opts; } +bool IsInCurrentlyGeneratingCrate(Context file) { + return file.generator_context().is_file_in_current_crate(&file.desc()); +} + +bool IsInCurrentlyGeneratingCrate(Context message) { + return message.generator_context().is_file_in_current_crate( + message.desc().file()); +} + } // namespace rust } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/rust/context.h b/src/google/protobuf/compiler/rust/context.h index 1158fbd795..affe8aee1b 100644 --- a/src/google/protobuf/compiler/rust/context.h +++ b/src/google/protobuf/compiler/rust/context.h @@ -8,10 +8,14 @@ #ifndef GOOGLE_PROTOBUF_COMPILER_RUST_CONTEXT_H__ #define GOOGLE_PROTOBUF_COMPILER_RUST_CONTEXT_H__ +#include +#include + #include "absl/log/absl_log.h" #include "absl/status/statusor.h" #include "absl/strings/string_view.h" #include "absl/types/span.h" +#include "google/protobuf/descriptor.h" #include "google/protobuf/io/printer.h" namespace google { @@ -43,6 +47,26 @@ struct Options { static absl::StatusOr Parse(absl::string_view param); }; +class RustGeneratorContext { + public: + explicit RustGeneratorContext( + const std::vector* files_in_current_crate) + : files_in_current_crate_(*files_in_current_crate) {} + + const FileDescriptor* primary_file() const { + return files_in_current_crate_.front(); + } + + bool is_file_in_current_crate(const FileDescriptor* f) const { + return std::find(files_in_current_crate_.begin(), + files_in_current_crate_.end(), + f) != files_in_current_crate_.end(); + } + + private: + const std::vector& files_in_current_crate_; +}; + // A context for generating a particular kind of definition. // This type acts as an options struct (as in go/totw/173) for most of the // generator. @@ -52,14 +76,22 @@ struct Options { template class Context { public: - Context(const Options* opts, const Descriptor* desc, io::Printer* printer) - : opts_(opts), desc_(desc), printer_(printer) {} + Context(const Options* opts, const Descriptor* desc, + const RustGeneratorContext* rust_generator_context, + io::Printer* printer) + : opts_(opts), + desc_(desc), + rust_generator_context_(rust_generator_context), + printer_(printer) {} Context(const Context&) = default; Context& operator=(const Context&) = default; const Descriptor& desc() const { return *desc_; } const Options& opts() const { return *opts_; } + const RustGeneratorContext& generator_context() const { + return *rust_generator_context_; + } bool is_cpp() const { return opts_->kernel == Kernel::kCpp; } bool is_upb() const { return opts_->kernel == Kernel::kUpb; } @@ -70,16 +102,16 @@ class Context { // Creates a new context over a different descriptor. template Context WithDesc(const D& desc) const { - return Context(opts_, &desc, printer_); + return Context(opts_, &desc, rust_generator_context_, printer_); } template Context WithDesc(const D* desc) const { - return Context(opts_, desc, printer_); + return Context(opts_, desc, rust_generator_context_, printer_); } Context WithPrinter(io::Printer* printer) const { - return Context(opts_, desc_, printer); + return Context(opts_, desc_, rust_generator_context_, printer); } // Forwards to Emit(), which will likely be called all the time. @@ -97,8 +129,13 @@ class Context { private: const Options* opts_; const Descriptor* desc_; + const RustGeneratorContext* rust_generator_context_; io::Printer* printer_; }; + +bool IsInCurrentlyGeneratingCrate(Context file); +bool IsInCurrentlyGeneratingCrate(Context message); + } // namespace rust } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/rust/generator.cc b/src/google/protobuf/compiler/rust/generator.cc index 4027376102..3465672232 100644 --- a/src/google/protobuf/compiler/rust/generator.cc +++ b/src/google/protobuf/compiler/rust/generator.cc @@ -98,6 +98,7 @@ void EmitPubUseOfOwnMessages(Context& primary_file, pub use crate::$mod$::$Msg$; // TODO Address use for imported crates pub use crate::$mod$::$Msg$View; + pub use crate::$mod$::$Msg$Mut; )rs"); } } @@ -123,11 +124,7 @@ void EmitPubUseForImportedMessages(Context& primary_file, } // Emits all public imports of the current file -void EmitPublicImports( - Context& primary_file, - const std::vector& files_in_current_crate) { - absl::flat_hash_set files( - files_in_current_crate.begin(), files_in_current_crate.end()); +void EmitPublicImports(Context& primary_file) { for (int i = 0; i < primary_file.desc().public_dependency_count(); ++i) { auto dep_file = primary_file.desc().public_dependency(i); // If the publicly imported file is a src of the current `proto_library` @@ -137,8 +134,10 @@ void EmitPublicImports( // TODO: Handle the case where a non-primary src with the same // declared package as the primary src publicly imports a file that the // primary doesn't. - if (files.contains(dep_file)) continue; auto dep = primary_file.WithDesc(dep_file); + if (IsInCurrentlyGeneratingCrate(dep)) { + return; + } EmitPubUseForImportedMessages(primary_file, dep); } } @@ -206,7 +205,13 @@ bool RustGenerator::Generate(const FileDescriptor* file_desc, return false; } - Context file(&*opts, file_desc, nullptr); + std::vector files_in_current_crate; + generator_context->ListParsedFiles(&files_in_current_crate); + + RustGeneratorContext rust_generator_context(&files_in_current_crate); + + Context file(&*opts, file_desc, &rust_generator_context, + nullptr); auto outfile = absl::WrapUnique(generator_context->Open(GetRsFile(file))); io::Printer printer(outfile.get()); @@ -228,15 +233,13 @@ bool RustGenerator::Generate(const FileDescriptor* file_desc, )rs"); - std::vector files_in_current_crate; - generator_context->ListParsedFiles(&files_in_current_crate); std::vector> file_contexts; for (const FileDescriptor* f : files_in_current_crate) { file_contexts.push_back(file.WithDesc(*f)); } // Generating the primary file? - if (file_desc == files_in_current_crate.front()) { + if (file_desc == rust_generator_context.primary_file()) { auto non_primary_srcs = absl::MakeConstSpan(file_contexts).subspan(1); DeclareSubmodulesForNonPrimarySrcs(file, non_primary_srcs); @@ -252,7 +255,7 @@ bool RustGenerator::Generate(const FileDescriptor* file_desc, } } - EmitPublicImports(file, files_in_current_crate); + EmitPublicImports(file); std::unique_ptr thunks_cc; std::unique_ptr thunks_printer; diff --git a/src/google/protobuf/compiler/rust/message.cc b/src/google/protobuf/compiler/rust/message.cc index 5b4a2fd746..7a73e93101 100644 --- a/src/google/protobuf/compiler/rust/message.cc +++ b/src/google/protobuf/compiler/rust/message.cc @@ -163,37 +163,169 @@ void MessageDrop(Context msg) { )rs"); } -// TODO: deferring on strings and bytes for now, eventually this -// check will go away as we support more than just simple scalars -bool IsSimpleScalar(FieldDescriptor::Type type) { - return type == FieldDescriptor::TYPE_DOUBLE || - type == FieldDescriptor::TYPE_FLOAT || - type == FieldDescriptor::TYPE_INT32 || - type == FieldDescriptor::TYPE_INT64 || - type == FieldDescriptor::TYPE_UINT32 || - type == FieldDescriptor::TYPE_UINT64 || - type == FieldDescriptor::TYPE_SINT32 || - type == FieldDescriptor::TYPE_SINT64 || - type == FieldDescriptor::TYPE_FIXED32 || - type == FieldDescriptor::TYPE_FIXED64 || - type == FieldDescriptor::TYPE_SFIXED32 || - type == FieldDescriptor::TYPE_SFIXED64 || - type == FieldDescriptor::TYPE_BOOL; +void GetterForViewOrMut(Context field, bool is_mut) { + auto fieldName = field.desc().name(); + auto fieldType = field.desc().type(); + auto getter_thunk = Thunk(field, "get"); + auto setter_thunk = Thunk(field, "set"); + auto clearer_thunk = Thunk(field, "clear"); + // If we're dealing with a Mut, the getter must be supplied + // self.inner.msg() whereas a View has to be supplied self.msg + auto self = is_mut ? "self.inner.msg()" : "self.msg"; + + if (fieldType == FieldDescriptor::TYPE_MESSAGE) { + Context d = field.WithDesc(field.desc().message_type()); + // TODO: support messages which are defined in other crates. + if (!IsInCurrentlyGeneratingCrate(d)) { + return; + } + auto prefix = "crate::" + GetCrateRelativeQualifiedPath(d); + field.Emit( + { + {"prefix", prefix}, + {"field", fieldName}, + {"self", self}, + {"getter_thunk", getter_thunk}, + // TODO: dedupe with singular_message.cc + { + "view_body", + [&] { + if (field.is_upb()) { + field.Emit({}, R"rs( + let submsg = unsafe { $getter_thunk$($self$) }; + match submsg { + None => $prefix$View::new($pbi$::Private, + $pbr$::ScratchSpace::zeroed_block($pbi$::Private)), + Some(field) => $prefix$View::new($pbi$::Private, field), + } + )rs"); + } else { + field.Emit({}, R"rs( + let submsg = unsafe { $getter_thunk$($self$) }; + $prefix$View::new($pbi$::Private, submsg) + )rs"); + } + }, + }, + }, + R"rs( + pub fn r#$field$(&self) -> $prefix$View { + $view_body$ + } + )rs"); + return; + } + + auto rsType = PrimitiveRsTypeName(field.desc()); + if (fieldType == FieldDescriptor::TYPE_STRING) { + field.Emit({{"field", fieldName}, + {"self", self}, + {"getter_thunk", getter_thunk}, + {"setter_thunk", setter_thunk}, + {"RsType", rsType}, + {"maybe_mutator", + [&] { + if (is_mut) { + field.Emit({}, R"rs( + pub fn r#$field$_mut(&self) -> $pb$::Mut<'_, $RsType$> { + static VTABLE: $pbi$::BytesMutVTable = + $pbi$::BytesMutVTable::new( + $pbi$::Private, + $getter_thunk$, + $setter_thunk$, + ); + + unsafe { + <$pb$::Mut<$RsType$>>::from_inner( + $pbi$::Private, + $pbi$::RawVTableMutator::new( + $pbi$::Private, + self.inner, + &VTABLE, + ) + ) + } + } + )rs"); + } + }}}, + R"rs( + pub fn r#$field$(&self) -> $pb$::View<'_, $RsType$> { + let s = unsafe { $getter_thunk$($self$).as_ref() }; + unsafe { __pb::ProtoStr::from_utf8_unchecked(s) } + } + + $maybe_mutator$ + )rs"); + } else if (fieldType == FieldDescriptor::TYPE_BYTES) { + field.Emit( + { + {"field", fieldName}, + {"self", self}, + {"getter_thunk", getter_thunk}, + {"RsType", rsType}, + }, + R"rs( + pub fn r#$field$(&self) -> $pb$::View<'_, $RsType$> { + unsafe { $getter_thunk$($self$).as_ref() } + } + )rs"); + } else { + field.Emit({{"field", fieldName}, + {"getter_thunk", getter_thunk}, + {"setter_thunk", setter_thunk}, + {"clearer_thunk", clearer_thunk}, + {"self", self}, + {"RsType", rsType}, + {"maybe_mutator", + [&] { + // TODO: once the rust public api is accessible, + // by tooling, ensure that this only appears for the + // mutational pathway + if (is_mut && fieldType) { + field.Emit({}, R"rs( + pub fn r#$field$_mut(&self) -> $pb$::Mut<'_, $RsType$> { + static VTABLE: $pbi$::PrimitiveVTable<$RsType$> = + $pbi$::PrimitiveVTable::new( + $pbi$::Private, + $getter_thunk$, + $setter_thunk$); + $pb$::PrimitiveMut::from_inner( + $pbi$::Private, + unsafe { + $pbi$::RawVTableMutator::new($pbi$::Private, + self.inner, + &VTABLE) + }) + } + )rs"); + } + }}}, + R"rs( + pub fn r#$field$(&self) -> $pb$::View<'_, $RsType$> { + unsafe { $getter_thunk$($self$) } + } + + $maybe_mutator$ + )rs"); + } } -void GenerateSubView(Context field) { - field.Emit( - { - {"field", field.desc().name()}, - {"getter_thunk", Thunk(field, "get")}, - {"Scalar", PrimitiveRsTypeName(field.desc())}, - }, - R"rs( - pub fn r#$field$(&self) -> $Scalar$ { unsafe { - $getter_thunk$(self.msg) - } } - )rs"); +void AccessorsForViewOrMut(Context msg, bool is_mut) { + for (int i = 0; i < msg.desc().field_count(); ++i) { + auto field = msg.WithDesc(*msg.desc().field(i)); + if (field.desc().is_repeated()) continue; + // TODO - add cord support + if (field.desc().options().has_ctype()) continue; + // TODO + if (field.desc().type() == FieldDescriptor::TYPE_ENUM || + field.desc().type() == FieldDescriptor::TYPE_GROUP) + continue; + GetterForViewOrMut(field, is_mut); + msg.printer().PrintRaw("\n"); + } } + } // namespace void GenerateRs(Context msg) { @@ -202,74 +334,70 @@ void GenerateRs(Context msg) { return; } msg.Emit( - { - {"Msg", msg.desc().name()}, - {"Msg::new", [&] { MessageNew(msg); }}, - {"Msg::serialize", [&] { MessageSerialize(msg); }}, - {"Msg::deserialize", [&] { MessageDeserialize(msg); }}, - {"Msg::drop", [&] { MessageDrop(msg); }}, - {"Msg_externs", [&] { MessageExterns(msg); }}, - {"accessor_fns", - [&] { - for (int i = 0; i < msg.desc().field_count(); ++i) { - auto field = msg.WithDesc(*msg.desc().field(i)); - msg.Emit({{"comment", FieldInfoComment(field)}}, R"rs( + {{"Msg", msg.desc().name()}, + {"Msg::new", [&] { MessageNew(msg); }}, + {"Msg::serialize", [&] { MessageSerialize(msg); }}, + {"Msg::deserialize", [&] { MessageDeserialize(msg); }}, + {"Msg::drop", [&] { MessageDrop(msg); }}, + {"Msg_externs", [&] { MessageExterns(msg); }}, + {"accessor_fns", + [&] { + for (int i = 0; i < msg.desc().field_count(); ++i) { + auto field = msg.WithDesc(*msg.desc().field(i)); + msg.Emit({{"comment", FieldInfoComment(field)}}, R"rs( // $comment$ )rs"); - GenerateAccessorMsgImpl(field); - msg.printer().PrintRaw("\n"); - } - }}, - {"oneof_accessor_fns", - [&] { - for (int i = 0; i < msg.desc().real_oneof_decl_count(); ++i) { - GenerateOneofAccessors( - msg.WithDesc(*msg.desc().real_oneof_decl(i))); - msg.printer().PrintRaw("\n"); - } - }}, - {"accessor_externs", - [&] { - for (int i = 0; i < msg.desc().field_count(); ++i) { - GenerateAccessorExternC(msg.WithDesc(*msg.desc().field(i))); - msg.printer().PrintRaw("\n"); - } - }}, - {"oneof_externs", - [&] { - for (int i = 0; i < msg.desc().real_oneof_decl_count(); ++i) { - GenerateOneofExternC( - msg.WithDesc(*msg.desc().real_oneof_decl(i))); - msg.printer().PrintRaw("\n"); - } - }}, - {"nested_msgs", - [&] { - // If we have no nested types or oneofs, bail out without emitting - // an empty mod SomeMsg_. - if (msg.desc().nested_type_count() == 0 && - msg.desc().real_oneof_decl_count() == 0) { - return; - } - msg.Emit({{"Msg", msg.desc().name()}, - {"nested_msgs", - [&] { - for (int i = 0; i < msg.desc().nested_type_count(); - ++i) { - auto nested_msg = - msg.WithDesc(msg.desc().nested_type(i)); - GenerateRs(nested_msg); - } - }}, - {"oneofs", - [&] { - for (int i = 0; - i < msg.desc().real_oneof_decl_count(); ++i) { - GenerateOneofDefinition( - msg.WithDesc(*msg.desc().real_oneof_decl(i))); - } - }}}, - R"rs( + GenerateAccessorMsgImpl(field); + msg.printer().PrintRaw("\n"); + } + }}, + {"oneof_accessor_fns", + [&] { + for (int i = 0; i < msg.desc().real_oneof_decl_count(); ++i) { + GenerateOneofAccessors( + msg.WithDesc(*msg.desc().real_oneof_decl(i))); + msg.printer().PrintRaw("\n"); + } + }}, + {"accessor_externs", + [&] { + for (int i = 0; i < msg.desc().field_count(); ++i) { + GenerateAccessorExternC(msg.WithDesc(*msg.desc().field(i))); + msg.printer().PrintRaw("\n"); + } + }}, + {"oneof_externs", + [&] { + for (int i = 0; i < msg.desc().real_oneof_decl_count(); ++i) { + GenerateOneofExternC(msg.WithDesc(*msg.desc().real_oneof_decl(i))); + msg.printer().PrintRaw("\n"); + } + }}, + {"nested_msgs", + [&] { + // If we have no nested types or oneofs, bail out without emitting + // an empty mod SomeMsg_. + if (msg.desc().nested_type_count() == 0 && + msg.desc().real_oneof_decl_count() == 0) { + return; + } + msg.Emit( + {{"Msg", msg.desc().name()}, + {"nested_msgs", + [&] { + for (int i = 0; i < msg.desc().nested_type_count(); ++i) { + auto nested_msg = msg.WithDesc(msg.desc().nested_type(i)); + GenerateRs(nested_msg); + } + }}, + {"oneofs", + [&] { + for (int i = 0; i < msg.desc().real_oneof_decl_count(); ++i) { + GenerateOneofDefinition( + msg.WithDesc(*msg.desc().real_oneof_decl(i))); + } + }}}, + R"rs( #[allow(non_snake_case)] pub mod $Msg$_ { $nested_msgs$ @@ -277,18 +405,9 @@ void GenerateRs(Context msg) { $oneofs$ } // mod $Msg$_ )rs"); - }}, - {"subviews", - [&] { - for (int i = 0; i < msg.desc().field_count(); ++i) { - auto field = msg.WithDesc(*msg.desc().field(i)); - if (field.desc().is_repeated()) continue; - if (!IsSimpleScalar(field.desc().type())) continue; - GenerateSubView(field); - msg.printer().PrintRaw("\n"); - } - }}, - }, + }}, + {"accessor_fns_for_views", [&] { AccessorsForViewOrMut(msg, false); }}, + {"accessor_fns_for_muts", [&] { AccessorsForViewOrMut(msg, true); }}}, R"rs( #[allow(non_camel_case_types)] // TODO: Implement support for debug redaction @@ -321,7 +440,7 @@ void GenerateRs(Context msg) { pub fn new(_private: $pbi$::Private, msg: $pbi$::RawMessage) -> Self { Self { msg, _phantom: std::marker::PhantomData } } - $subviews$ + $accessor_fns_for_views$ } // SAFETY: @@ -345,17 +464,34 @@ void GenerateRs(Context msg) { } impl<'a> $pb$::SettableValue<$Msg$> for $Msg$View<'a> { - fn set_on(self, _private: $pb$::__internal::Private, _mutator: $pb$::Mut<$Msg$>) { + fn set_on<'b>(self, _private: $pb$::__internal::Private, _mutator: $pb$::Mut<'b, $Msg$>) + where + $Msg$: 'b { todo!() } } #[derive(Debug)] #[allow(dead_code)] + #[allow(non_camel_case_types)] pub struct $Msg$Mut<'a> { inner: $pbr$::MutatorMessageRef<'a>, } + impl<'a> $Msg$Mut<'a> { + #[doc(hidden)] + pub fn new(_private: $pbi$::Private, + parent: &'a mut $pbr$::MessageInner, + msg: $pbi$::RawMessage) + -> Self { + Self { + inner: $pbr$::MutatorMessageRef::from_parent( + $pbi$::Private, parent, msg) + } + } + $accessor_fns_for_muts$ + } + // SAFETY: // - `$Msg$Mut` does not perform any shared mutation. // - `$Msg$Mut` is not `Send`, and so even in the presence of mutator diff --git a/src/google/protobuf/compiler/rust/naming.cc b/src/google/protobuf/compiler/rust/naming.cc index bb1c35a3e2..6685493c04 100644 --- a/src/google/protobuf/compiler/rust/naming.cc +++ b/src/google/protobuf/compiler/rust/naming.cc @@ -8,13 +8,14 @@ #include "google/protobuf/compiler/rust/naming.h" #include +#include #include "absl/log/absl_log.h" -#include "absl/strings/match.h" #include "absl/strings/str_cat.h" +#include "absl/strings/str_join.h" #include "absl/strings/str_replace.h" +#include "absl/strings/str_split.h" #include "absl/strings/string_view.h" -#include "absl/strings/strip.h" #include "absl/strings/substitute.h" #include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/compiler/rust/context.h" @@ -83,7 +84,10 @@ std::string Thunk(Context field, absl::string_view op) { if (field.is_upb() && op == "get") { // upb getter is simply the field name (no "get" in the name). format = "_$1"; - } else if (field.is_upb() && (op == "case")) { + } else if (field.is_upb() && op == "get_mut") { + // same as above, with with `mutable` prefix + format = "_mutable_$1"; + } else if (field.is_upb() && op == "case") { // some upb functions are in the order x_op compared to has/set/clear which // are in the other order e.g. op_x. format = "_$1_$0"; @@ -95,8 +99,8 @@ std::string Thunk(Context field, absl::string_view op) { return thunk; } -std::string ThunkRepeated(Context field, - absl::string_view op) { +std::string ThunkMapOrRepeated(Context field, + absl::string_view op) { if (!field.is_upb()) { return Thunk(field, op); } @@ -104,9 +108,10 @@ std::string ThunkRepeated(Context field, std::string thunk = absl::StrCat("_", FieldPrefix(field)); absl::string_view format; if (op == "get") { - format = "_$1_upb_array"; + format = field.desc().is_map() ? "_$1_upb_map" : "_$1_upb_array"; } else if (op == "get_mut") { - format = "_$1_mutable_upb_array"; + format = + field.desc().is_map() ? "_$1_mutable_upb_map" : "_$1_mutable_upb_array"; } else { return Thunk(field, op); } @@ -118,8 +123,8 @@ std::string ThunkRepeated(Context field, } // namespace std::string Thunk(Context field, absl::string_view op) { - if (field.desc().is_repeated()) { - return ThunkRepeated(field, op); + if (field.desc().is_map() || field.desc().is_repeated()) { + return ThunkMapOrRepeated(field, op); } return Thunk(field, op); } @@ -166,10 +171,46 @@ std::string PrimitiveRsTypeName(const FieldDescriptor& desc) { return ""; } +// Constructs a string of the Rust modules which will contain the message. +// +// Example: Given a message 'NestedMessage' which is defined in package 'x.y' +// which is inside 'ParentMessage', the message will be placed in the +// x::y::ParentMessage_ Rust module, so this function will return the string +// "x::y::ParentMessage_::". +// +// If the message has no package and no containing messages then this returns +// empty string. std::string RustModule(Context msg) { - absl::string_view package = msg.desc().file()->package(); - if (package.empty()) return ""; - return absl::StrCat("", absl::StrReplaceAll(package, {{".", "::"}})); + const Descriptor& desc = msg.desc(); + + std::vector modules; + + std::vector package_modules = + absl::StrSplit(desc.file()->package(), '.', absl::SkipEmpty()); + + modules.insert(modules.begin(), package_modules.begin(), + package_modules.end()); + + // Innermost to outermost order. + std::vector modules_from_containing_types; + const Descriptor* parent = desc.containing_type(); + while (parent != nullptr) { + modules_from_containing_types.push_back(absl::StrCat(parent->name(), "_")); + parent = parent->containing_type(); + } + + // Add the modules from containing messages (rbegin/rend to get them in outer + // to inner order). + modules.insert(modules.end(), modules_from_containing_types.rbegin(), + modules_from_containing_types.rend()); + + // If there is any modules at all, push an empty string on the end so that + // we get the trailing :: + if (!modules.empty()) { + modules.push_back(""); + } + + return absl::StrJoin(modules, "::"); } std::string RustInternalModuleName(Context file) { @@ -179,19 +220,7 @@ std::string RustInternalModuleName(Context file) { } std::string GetCrateRelativeQualifiedPath(Context msg) { - std::string name = msg.desc().full_name(); - if (msg.desc().file()->package().empty()) { - return name; - } - // when computing the relative path, we don't want the package name, so we - // strip that out - name = - std::string(absl::StripPrefix(name, msg.desc().file()->package() + ".")); - // proto nesting is marked with periods in .proto files -- this gets - // translated to delimiting via _:: in terra rust - absl::StrReplaceAll({{".", "_::"}}, &name); - - return absl::StrCat(RustModule(msg), "::", name); + return absl::StrCat(RustModule(msg), msg.desc().name()); } std::string FieldInfoComment(Context field) { diff --git a/src/google/protobuf/compiler/rust/oneof.cc b/src/google/protobuf/compiler/rust/oneof.cc index 2cdeeac203..83350289d6 100644 --- a/src/google/protobuf/compiler/rust/oneof.cc +++ b/src/google/protobuf/compiler/rust/oneof.cc @@ -9,6 +9,7 @@ #include +#include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" #include "google/protobuf/compiler/cpp/helpers.h" #include "google/protobuf/compiler/rust/context.h" @@ -91,29 +92,36 @@ std::string oneofCaseEnumName(const OneofDescriptor& desc) { } // TODO: Promote up to naming.h once all types can be spelled. -std::string RsTypeName(const FieldDescriptor& desc) { +std::string RsTypeName(Context field) { + const auto& desc = field.desc(); + + // TODO: Fields with a ctype set not supported in v0.6 api. + if (desc.options().has_ctype()) { + return ""; + } + switch (desc.type()) { case FieldDescriptor::TYPE_MESSAGE: + return absl::StrCat("crate::", GetCrateRelativeQualifiedPath( + field.WithDesc(desc.message_type()))); case FieldDescriptor::TYPE_ENUM: case FieldDescriptor::TYPE_GROUP: - case FieldDescriptor::TYPE_STRING: - case FieldDescriptor::TYPE_BYTES: return ""; default: return PrimitiveRsTypeName(desc); } } -std::string RsTypeNameView(const FieldDescriptor& desc) { - std::string type = RsTypeName(desc); +std::string RsTypeNameView(Context field) { + std::string type = RsTypeName(field); if (type.empty()) return ""; - return "View<'msg, " + type + ">"; + return absl::StrCat("::__pb::View<'msg, ", type, ">"); } -std::string RsTypeNameMut(const FieldDescriptor& desc) { - std::string type = RsTypeName(desc); +std::string RsTypeNameMut(Context field) { + std::string type = RsTypeName(field); if (type.empty()) return ""; - return "Mut<'msg, " + type + ">"; + return absl::StrCat("::__pb::Mut<'msg, ", type, ">"); } } // namespace @@ -127,30 +135,30 @@ void GenerateOneofDefinition(Context oneof) { {"view_fields", [&] { for (int i = 0; i < desc.field_count(); ++i) { - const auto& field = desc.field(i); - std::string rs_type = RsTypeNameView(*field); + const auto& field = *desc.field(i); + std::string rs_type = RsTypeNameView(oneof.WithDesc(field)); if (rs_type.empty()) { continue; } - oneof.Emit({{"name", ToCamelCase(field->name())}, + oneof.Emit({{"name", ToCamelCase(field.name())}, {"type", rs_type}, - {"number", std::to_string(field->number())}}, - R"rs($name$($pb$::$type$) = $number$, + {"number", std::to_string(field.number())}}, + R"rs($name$($type$) = $number$, )rs"); } }}, {"mut_fields", [&] { for (int i = 0; i < desc.field_count(); ++i) { - const auto& field = desc.field(i); - std::string rs_type = RsTypeNameMut(*field); + const auto& field = *desc.field(i); + std::string rs_type = RsTypeNameMut(oneof.WithDesc(field)); if (rs_type.empty()) { continue; } - oneof.Emit({{"name", ToCamelCase(field->name())}, + oneof.Emit({{"name", ToCamelCase(field.name())}, {"type", rs_type}, - {"number", std::to_string(field->number())}}, - R"rs($name$($pb$::$type$) = $number$, + {"number", std::to_string(field.number())}}, + R"rs($name$($type$) = $number$, )rs"); } }}}, @@ -220,15 +228,15 @@ void GenerateOneofAccessors(Context oneof) { {"view_cases", [&] { for (int i = 0; i < desc.field_count(); ++i) { - const auto& field = desc.field(i); - std::string rs_type = RsTypeNameView(*field); + const auto& field = *desc.field(i); + std::string rs_type = RsTypeNameView(oneof.WithDesc(field)); if (rs_type.empty()) { continue; } oneof.Emit( { - {"case", ToCamelCase(field->name())}, - {"rs_getter", field->name()}, + {"case", ToCamelCase(field.name())}, + {"rs_getter", field.name()}, {"type", rs_type}, }, R"rs($Msg$_::$case_enum_name$::$case$ => $Msg$_::$view_enum_name$::$case$(self.$rs_getter$()), @@ -238,21 +246,36 @@ void GenerateOneofAccessors(Context oneof) { {"mut_cases", [&] { for (int i = 0; i < desc.field_count(); ++i) { - const auto& field = desc.field(i); - std::string rs_type = RsTypeNameMut(*field); + const auto& field = *desc.field(i); + std::string rs_type = RsTypeNameMut(oneof.WithDesc(field)); if (rs_type.empty()) { continue; } - // TODO: Uncomment this to allow mut once - // _mut() on singular fields with presence is implemented. - /*oneof.Emit({ - {"case", ToCamelCase(field->name())}, - {"rs_getter", field->name() + "_mut"}, - {"type", rs_type}, - }, + oneof.Emit( + {{"case", ToCamelCase(field.name())}, + {"rs_mut_getter", field.name() + "_mut"}, + {"type", rs_type}, + + // Any extra behavior needed to map the mut getter into the + // unwrapped Mut<>. Right now Message's _mut already returns + // the Mut directly, but for scalars the accessor will return + // an Optional which we then grab the mut by doing + // .try_into_mut().unwrap(). + // + // Note that this unwrap() is safe because the flow is: + // 1) Find out which oneof field is already set (if any) + // 2) If a field is set, call the corresponding field's _mut() + // and wrap the result in the SomeOneofMut enum. + // The unwrap() will only ever panic if the which oneof enum + // disagrees with the corresponding field presence which. + // TODO: If the message _mut accessor returns + // Optional<> then this conditional behavior should be removed. + {"into_mut_transform", + field.type() == FieldDescriptor::TYPE_MESSAGE + ? "" + : ".try_into_mut().unwrap()"}}, R"rs($Msg$_::$case_enum_name$::$case$ => - $Msg$_::$mut_enum_name$::$case$(self.$rs_getter$()), )rs"); - */ + $Msg$_::$mut_enum_name$::$case$(self.$rs_mut_getter$()$into_mut_transform$), )rs"); } }}, {"case_thunk", Thunk(oneof, "case")}}, diff --git a/src/google/protobuf/compiler/versions.cc b/src/google/protobuf/compiler/versions.cc new file mode 100644 index 0000000000..8927d8c03d --- /dev/null +++ b/src/google/protobuf/compiler/versions.cc @@ -0,0 +1,58 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "google/protobuf/compiler/versions.h" + +#include +#include + +#include "absl/log/absl_check.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_split.h" +#include "absl/strings/string_view.h" +#include "google/protobuf/compiler/plugin.pb.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace internal { +Version ParseProtobufVersion(absl::string_view version) { + ABSL_CHECK(!version.empty()) << "version cannot be empty."; + Version result; + std::vector parts = absl::StrSplit(version, '-'); + ABSL_CHECK(parts.size() <= 2) + << "version cannot have more than one suffix annotated by \"-\"."; + if (parts.size() == 2) result.set_suffix(absl::StrCat("-", parts[1])); + parts = absl::StrSplit(parts[0], '.'); + ABSL_CHECK(parts.size() == 3) + << "version string must provide major, minor and micro numbers."; + result.set_major(std::stoi(parts[0])); + result.set_minor(std::stoi(parts[1])); + result.set_patch(std::stoi(parts[2])); + return result; +} +} // namespace internal + +const Version& GetProtobufCPPVersion() { + // Heap-allocated versions to avoid re-parsing version strings + static const Version* cpp_version = + new Version(internal::ParseProtobufVersion(PROTOBUF_CPP_VERSION_STRING)); + return *cpp_version; +} +const Version& GetProtobufJavaVersion() { + static const Version* java_version = + new Version(internal::ParseProtobufVersion(PROTOBUF_JAVA_VERSION_STRING)); + return *java_version; +} +const Version& GetProtobufPythonVersion() { + static const Version* python_version = new Version( + internal::ParseProtobufVersion(PROTOBUF_PYTHON_VERSION_STRING)); + return *python_version; +} +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/versions.h b/src/google/protobuf/compiler/versions.h index 615944f8be..b2ac1c34f6 100644 --- a/src/google/protobuf/compiler/versions.h +++ b/src/google/protobuf/compiler/versions.h @@ -31,10 +31,17 @@ #ifndef GOOGLE_PROTOBUF_VERSIONS_H__ #define GOOGLE_PROTOBUF_VERSIONS_H__ -#include "google/protobuf/compiler/versions_suffix.h" +#include "absl/strings/string_view.h" +#include "google/protobuf/compiler/plugin.pb.h" + +// Must be included last. +#include "google/protobuf/port_def.inc" // Defines compiler version strings for Protobuf code generators. // +// When they are suffixed with "-dev", they reflect the version of the next +// release, otherwise the current released version. +// // Currently, they are embedded into comments at each gencode for public // Protobuf C++, Java and Python. Further, we will add version strings for rest // of languages in version.json, and they will be used to validate version @@ -46,8 +53,24 @@ // // Please avoid changing them manually, as they should be updated automatically // by Protobuf release process. -#define PROTOBUF_CPP_VERSION_STRING "4.24.0" PROTOBUF_GENCODE_VERSION_SUFFIX -#define PROTOBUF_JAVA_VERSION_STRING "3.24.0" PROTOBUF_GENCODE_VERSION_SUFFIX -#define PROTOBUF_PYTHON_VERSION_STRING "4.24.0" PROTOBUF_GENCODE_VERSION_SUFFIX +#define PROTOBUF_CPP_VERSION_STRING "4.26.0-dev" +#define PROTOBUF_JAVA_VERSION_STRING "3.26.0-dev" +#define PROTOBUF_PYTHON_VERSION_STRING "4.26.0-dev" + +namespace google { +namespace protobuf { +namespace compiler { +namespace internal { +// For internal use to parse the Protobuf language version strings. +PROTOC_EXPORT Version ParseProtobufVersion(absl::string_view version); +} // namespace internal +// Gets the version message according to the version strings defined above. +const Version& GetProtobufCPPVersion(); +const Version& GetProtobufJavaVersion(); +const Version& GetProtobufPythonVersion(); +} // namespace compiler +} // namespace protobuf +} // namespace google +#include "google/protobuf/port_undef.inc" #endif // GOOGLE_PROTOBUF_VERSIONS_H__ diff --git a/src/google/protobuf/compiler/versions_suffix.h b/src/google/protobuf/compiler/versions_suffix.h deleted file mode 100644 index 5fd30faf0d..0000000000 --- a/src/google/protobuf/compiler/versions_suffix.h +++ /dev/null @@ -1,26 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd - -#ifndef GOOGLE_PROTOBUF_COMPILER_VERSIONS_SUFFIX_H__ -#define GOOGLE_PROTOBUF_COMPILER_VERSIONS_SUFFIX_H__ - -// Defines compiler version suffix for Protobuf code generators. -// -// It is defined separately from the language-specific version strings that are -// in versions.h to prevent it from being overwritten when merging Protobuf -// release branches back to main, as the suffix "-main" should stay in the -// Protobuf github main branch. -// -// Note that the version suffix "-main" implies the main branch. For example, -// 4.25-main reflects a main branch version under development towards 25.x -// release, and thus should not be used for production. -// -// Please avoid changing it manually, as they should be updated automatically by -// the Protobuf release process. -#define PROTOBUF_GENCODE_VERSION_SUFFIX "-main" - -#endif // GOOGLE_PROTOBUF_COMPILER_VERSIONS_SUFFIX_H__ diff --git a/src/google/protobuf/compiler/versions_test.cc b/src/google/protobuf/compiler/versions_test.cc new file mode 100644 index 0000000000..31e65c10ae --- /dev/null +++ b/src/google/protobuf/compiler/versions_test.cc @@ -0,0 +1,51 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +#include "google/protobuf/compiler/versions.h" + +#include +#include +#include "google/protobuf/test_textproto.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace internal { +namespace { +TEST(ParseProtobufVersionTest, EmptyVersionString) { + EXPECT_DEATH({ ParseProtobufVersion(""); }, "version cannot be empty."); +} + +TEST(ParseProtobufVersionTest, MissingVersionSegment) { + EXPECT_DEATH({ ParseProtobufVersion("3.26-dev"); }, + "version string must provide major, minor and micro numbers."); +} + +TEST(ParseProtobufVersionTest, RedundantVersionSuffix) { + EXPECT_DEATH({ ParseProtobufVersion("3.26-dev-rc1"); }, + "version cannot have more than one suffix annotated by \"-\"."); +} + +TEST(ParseProtobufVersionTest, FullVersionWithRCSuffix) { + EXPECT_THAT(ParseProtobufVersion("3.26.2-rc1"), + EqualsProto(R"pb(major: 3 minor: 26 patch: 2 suffix: "-rc1")pb")); +} + +TEST(ParseProtobufVersionTest, FullVersionWithoutSuffix) { + EXPECT_THAT(ParseProtobufVersion("3.26.2"), + EqualsProto(R"pb(major: 3 minor: 26 patch: 2)pb")); +} + +TEST(ParseProtobufVersionTest, VersionWithDevSuffix) { + EXPECT_THAT(ParseProtobufVersion("3.26.0-dev"), + EqualsProto(R"pb(major: 3 minor: 26 patch: 0 suffix: "-dev")pb")); +} +} // namespace +} // namespace internal +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/cpp_edition_defaults.h b/src/google/protobuf/cpp_edition_defaults.h index 0e87733027..151455f2d8 100644 --- a/src/google/protobuf/cpp_edition_defaults.h +++ b/src/google/protobuf/cpp_edition_defaults.h @@ -5,7 +5,7 @@ // the C++ runtime. This is used for feature resolution under Editions. // NOLINTBEGIN // clang-format off -#define PROTOBUF_INTERNAL_CPP_EDITION_DEFAULTS "\n\026\022\021\010\001\020\002\030\002 \001(\0010\002\302>\002\010\001\030\346\007\n\026\022\021\010\002\020\001\030\001 \002(\0010\001\302>\002\010\000\030\347\007\n\026\022\021\010\001\020\001\030\001 \002(\0010\001\302>\002\010\000\030\350\007 \346\007(\350\007" +#define PROTOBUF_INTERNAL_CPP_EDITION_DEFAULTS "\n\026\022\021\010\001\020\002\030\002 \003(\0010\002\302>\002\010\001\030\346\007\n\026\022\021\010\002\020\001\030\001 \002(\0010\001\302>\002\010\000\030\347\007\n\026\022\021\010\001\020\001\030\001 \002(\0010\001\302>\002\010\000\030\350\007 \346\007(\350\007" // clang-format on // NOLINTEND diff --git a/src/google/protobuf/cpp_features.pb.cc b/src/google/protobuf/cpp_features.pb.cc index b7eee1a5fa..0d38ae0ace 100644 --- a/src/google/protobuf/cpp_features.pb.cc +++ b/src/google/protobuf/cpp_features.pb.cc @@ -1,5 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/cpp_features.proto +// Protobuf C++ Version: 4.26.0-dev #include "google/protobuf/cpp_features.pb.h" @@ -123,9 +124,6 @@ class CppFeatures::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_._has_bits_); - static void set_has_legacy_closed_enum(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } }; CppFeatures::CppFeatures(::google::protobuf::Arena* arena) @@ -160,12 +158,13 @@ inline void CppFeatures::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* CppFeatures::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { CppFeatures::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void CppFeatures::Clear() { // @@protoc_insertion_point(message_clear_start:pb.CppFeatures) @@ -200,6 +199,9 @@ const ::_pbi::TcParseTable<0, 1, 0, 0, 2> CppFeatures::_table_ = { offsetof(decltype(_table_), field_names), // no aux_entries &_CppFeatures_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::pb::CppFeatures>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // optional bool legacy_closed_enum = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { {::_pbi::TcParser::SingularVarintNoZag1(), @@ -258,7 +260,7 @@ const ::_pbi::TcParseTable<0, 1, 0, 0, 2> CppFeatures::_table_ = { } -void CppFeatures::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void CppFeatures::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:pb.CppFeatures) @@ -266,9 +268,11 @@ void CppFeatures::MergeImpl(::google::protobuf::Message& to_msg, const ::google: ::uint32_t cached_has_bits = 0; (void) cached_has_bits; - if ((from._impl_._has_bits_[0] & 0x00000001u) != 0) { - _this->_internal_set_legacy_closed_enum(from._internal_legacy_closed_enum()); + cached_has_bits = from._impl_._has_bits_[0]; + if (cached_has_bits & 0x00000001u) { + _this->_impl_.legacy_closed_enum_ = from._impl_.legacy_closed_enum_; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -283,9 +287,6 @@ PROTOBUF_NOINLINE bool CppFeatures::IsInitialized() const { return true; } -::_pbi::CachedSize* CppFeatures::AccessCachedSize() const { - return &_impl_._cached_size_; -} void CppFeatures::InternalSwap(CppFeatures* PROTOBUF_RESTRICT other) { using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); @@ -294,14 +295,15 @@ void CppFeatures::InternalSwap(CppFeatures* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata CppFeatures::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_getter, &descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_once, - file_level_metadata_google_2fprotobuf_2fcpp_5ffeatures_2eproto[0]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_once, + file_level_metadata_google_2fprotobuf_2fcpp_5ffeatures_2eproto[0]); } -PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 -::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::FeatureSet, - ::google::protobuf::internal::MessageTypeTraits< ::pb::CppFeatures >, 11, false> - cpp(kCppFieldNumber); +PROTOBUF_CONSTINIT PROTOBUF_EXPORT + PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi:: + ExtensionIdentifier<::google::protobuf::FeatureSet, ::_pbi::MessageTypeTraits< ::pb::CppFeatures >, + 11, false> + cpp(kCppFieldNumber, &::pb::_CppFeatures_default_instance_); // @@protoc_insertion_point(namespace_scope) } // namespace pb namespace google { diff --git a/src/google/protobuf/cpp_features.pb.h b/src/google/protobuf/cpp_features.pb.h index 3b470431e3..3a9558b878 100644 --- a/src/google/protobuf/cpp_features.pb.h +++ b/src/google/protobuf/cpp_features.pb.h @@ -1,6 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/cpp_features.proto -// Protobuf C++ Version: 4.24.0-main +// Protobuf C++ Version: 4.26.0-dev #ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcpp_5ffeatures_2eproto_2epb_2eh #define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcpp_5ffeatures_2eproto_2epb_2eh @@ -11,17 +11,11 @@ #include #include "google/protobuf/port_def.inc" -#if PROTOBUF_VERSION < 4024000 -#error "This file was generated by a newer version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please update" -#error "your headers." -#endif // PROTOBUF_VERSION - -#if 4024000 < PROTOBUF_MIN_PROTOC_VERSION -#error "This file was generated by an older version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please" -#error "regenerate this file with a newer version of protoc." -#endif // PROTOBUF_MIN_PROTOC_VERSION +#if PROTOBUF_VERSION != 4026000 +#error "Protobuf C++ gencode is built with an incompatible version of" +#error "Protobuf C++ headers/runtime. See" +#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp" +#endif #include "google/protobuf/port_undef.inc" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/arena.h" @@ -73,21 +67,18 @@ namespace pb { // ------------------------------------------------------------------- -class PROTOBUF_EXPORT CppFeatures final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:pb.CppFeatures) */ { +class PROTOBUF_EXPORT CppFeatures final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:pb.CppFeatures) */ { public: inline CppFeatures() : CppFeatures(nullptr) {} ~CppFeatures() override; - template - explicit PROTOBUF_CONSTEXPR CppFeatures(::google::protobuf::internal::ConstantInitialized); - - inline CppFeatures(const CppFeatures& from) - : CppFeatures(nullptr, from) {} - CppFeatures(CppFeatures&& from) noexcept - : CppFeatures() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR CppFeatures( + ::google::protobuf::internal::ConstantInitialized); + inline CppFeatures(const CppFeatures& from) : CppFeatures(nullptr, from) {} + inline CppFeatures(CppFeatures&& from) noexcept + : CppFeatures(nullptr, std::move(from)) {} inline CppFeatures& operator=(const CppFeatures& from) { CopyFrom(from); return *this; @@ -95,9 +86,9 @@ class PROTOBUF_EXPORT CppFeatures final : inline CppFeatures& operator=(CppFeatures&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -129,22 +120,17 @@ class PROTOBUF_EXPORT CppFeatures final : } static inline const CppFeatures* internal_default_instance() { return reinterpret_cast( - &_CppFeatures_default_instance_); - } - static constexpr int kIndexInFileMessages = - 0; - - friend void swap(CppFeatures& a, CppFeatures& b) { - a.Swap(&b); + &_CppFeatures_default_instance_); } + static constexpr int kIndexInFileMessages = 0; + friend void swap(CppFeatures& a, CppFeatures& b) { a.Swap(&b); } inline void Swap(CppFeatures* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -159,16 +145,18 @@ class PROTOBUF_EXPORT CppFeatures final : // implements Message ---------------------------------------------- CppFeatures* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const CppFeatures& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const CppFeatures& from) { - CppFeatures::MergeImpl(*this, from); - } + void MergeFrom(const CppFeatures& from) { CppFeatures::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -176,32 +164,33 @@ class PROTOBUF_EXPORT CppFeatures final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(CppFeatures* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "pb.CppFeatures"; - } - protected: + static ::absl::string_view FullMessageName() { return "pb.CppFeatures"; } + + protected: explicit CppFeatures(::google::protobuf::Arena* arena); CppFeatures(::google::protobuf::Arena* arena, const CppFeatures& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + CppFeatures(::google::protobuf::Arena* arena, CppFeatures&& from) noexcept + : CppFeatures(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kLegacyClosedEnumFieldNumber = 1, }; @@ -219,7 +208,6 @@ class PROTOBUF_EXPORT CppFeatures final : // @@protoc_insertion_point(class_scope:pb.CppFeatures) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 0, 1, 0, @@ -231,14 +219,13 @@ class PROTOBUF_EXPORT CppFeatures final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; bool legacy_closed_enum_; @@ -253,9 +240,10 @@ class PROTOBUF_EXPORT CppFeatures final : static const int kCppFieldNumber = 1000; -PROTOBUF_EXPORT extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::FeatureSet, - ::google::protobuf::internal::MessageTypeTraits< ::pb::CppFeatures >, 11, false > - cpp; +PROTOBUF_EXPORT extern ::google::protobuf::internal::ExtensionIdentifier< + ::google::protobuf::FeatureSet, ::google::protobuf::internal::MessageTypeTraits< ::pb::CppFeatures >, 11, + false> + cpp; // =================================================================== @@ -284,6 +272,7 @@ inline bool CppFeatures::legacy_closed_enum() const { } inline void CppFeatures::set_legacy_closed_enum(bool value) { _internal_set_legacy_closed_enum(value); + _impl_._has_bits_[0] |= 0x00000001u; // @@protoc_insertion_point(field_set:pb.CppFeatures.legacy_closed_enum) } inline bool CppFeatures::_internal_legacy_closed_enum() const { @@ -292,7 +281,6 @@ inline bool CppFeatures::_internal_legacy_closed_enum() const { } inline void CppFeatures::_internal_set_legacy_closed_enum(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000001u; _impl_.legacy_closed_enum_ = value; } diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 0f1cd6bc86..004be51c3b 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -36,6 +36,7 @@ #include "absl/log/absl_check.h" #include "absl/log/absl_log.h" #include "absl/memory/memory.h" +#include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/ascii.h" #include "absl/strings/escaping.h" @@ -54,7 +55,6 @@ #include "google/protobuf/cpp_features.pb.h" #include "google/protobuf/descriptor.pb.h" #include "google/protobuf/descriptor_database.h" -#include "google/protobuf/descriptor_legacy.h" #include "google/protobuf/descriptor_visitor.h" #include "google/protobuf/dynamic_message.h" #include "google/protobuf/feature_resolver.h" @@ -810,23 +810,6 @@ const char* const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = { "repeated", // LABEL_REPEATED }; -PROTOBUF_IGNORE_DEPRECATION_START -const char* FileDescriptor::SyntaxName(FileDescriptor::Syntax syntax) { - switch (syntax) { - case SYNTAX_PROTO2: - return "proto2"; - case SYNTAX_PROTO3: - return "proto3"; - case SYNTAX_EDITIONS: - return "editions"; - case SYNTAX_UNKNOWN: - return "unknown"; - } - ABSL_LOG(FATAL) << "can't reach here."; - return nullptr; -} -PROTOBUF_IGNORE_DEPRECATION_STOP - static const char* const kNonLinkedWeakMessageReplacementName = "google.protobuf.Empty"; #if !defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912) @@ -1092,14 +1075,16 @@ bool AllowedExtendeeInProto3(const std::string& name) { } const FeatureSetDefaults& GetCppFeatureSetDefaults() { - static const FeatureSetDefaults* default_spec = [] { - auto* defaults = new FeatureSetDefaults(); - internal::ParseNoReflection( - absl::string_view{PROTOBUF_INTERNAL_CPP_EDITION_DEFAULTS, - sizeof(PROTOBUF_INTERNAL_CPP_EDITION_DEFAULTS) - 1}, - *defaults); - return defaults; - }(); + static const FeatureSetDefaults* default_spec = + internal::OnShutdownDelete([] { + auto* defaults = new FeatureSetDefaults(); + internal::ParseNoReflection( + absl::string_view{ + PROTOBUF_INTERNAL_CPP_EDITION_DEFAULTS, + sizeof(PROTOBUF_INTERNAL_CPP_EDITION_DEFAULTS) - 1}, + *defaults); + return defaults; + }()); return *default_spec; } @@ -1178,6 +1163,25 @@ const FeatureSet& GetParentFeatures(const ServiceDescriptor* service) { const FeatureSet& GetParentFeatures(const MethodDescriptor* method) { return internal::InternalFeatureHelper::GetFeatures(*method->service()); } + +bool IsLegacyEdition(const FileDescriptor* file) { + return file->edition() < Edition::EDITION_2023; +} + +template +bool IsLegacyEdition(const DescriptorT* descriptor) { + return IsLegacyEdition(descriptor->file()); +} + +Edition GetDescriptorEdition(const FileDescriptor* descriptor) { + return descriptor->edition(); +} + +template +Edition GetDescriptorEdition(const DescriptorT* descriptor) { + return GetDescriptorEdition(descriptor->file()); +} + } // anonymous namespace // Contains tables specific to a particular file. These tables are not @@ -2720,6 +2724,7 @@ FileDescriptor::FileDescriptor() {} void FileDescriptor::CopyTo(FileDescriptorProto* proto) const { CopyHeadingTo(proto); + for (int i = 0; i < dependency_count(); i++) { proto->add_dependency(dependency(i)->name()); } @@ -2752,13 +2757,10 @@ void FileDescriptor::CopyHeadingTo(FileDescriptorProto* proto) const { proto->set_package(package()); } - // TODO: Also populate when syntax="proto2". - FileDescriptorLegacy::Syntax syntax = FileDescriptorLegacy(this).syntax(); - if (syntax == FileDescriptorLegacy::Syntax::SYNTAX_PROTO3 || - syntax == FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS) { - proto->set_syntax(FileDescriptorLegacy::SyntaxName(syntax)); - } - if (syntax == FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS) { + if (edition() == Edition::EDITION_PROTO3) { + proto->set_syntax("proto3"); + } else if (!IsLegacyEdition(this)) { + proto->set_syntax("editions"); proto->set_edition(edition()); } @@ -2855,8 +2857,7 @@ void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const { } // Some compilers do not allow static_cast directly between two enum types, // so we must cast to int first. - if (is_required() && FileDescriptorLegacy(file()).syntax() == - FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS) { + if (is_required() && !IsLegacyEdition(this)) { // Editions files have no required keyword, and we only set this label // during descriptor build. proto->set_label(static_cast( @@ -2865,9 +2866,7 @@ void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const { proto->set_label(static_cast( absl::implicit_cast(label()))); } - if (type() == TYPE_GROUP && - FileDescriptorLegacy(file()).syntax() == - FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS) { + if (type() == TYPE_GROUP && !IsLegacyEdition(this)) { // Editions files have no group keyword, and we only set this label // during descriptor build. proto->set_type(static_cast( @@ -3004,11 +3003,7 @@ void MethodDescriptor::CopyTo(MethodDescriptorProto* proto) const { namespace { bool IsGroupSyntax(const FieldDescriptor* desc) { - if (FileDescriptorLegacy(desc->file()).syntax() == - FileDescriptorLegacy::SYNTAX_EDITIONS) { - return false; - } - return desc->type() == FieldDescriptor::TYPE_GROUP; + return IsLegacyEdition(desc) && desc->type() == FieldDescriptor::TYPE_GROUP; } template @@ -3122,6 +3117,14 @@ bool FormatLineOptions(int depth, const Message& options, return !all_options.empty(); } +static std::string GetLegacySyntaxName(const FileDescriptor* file) { + if (file->edition() == Edition::EDITION_PROTO3) { + return "proto3"; + } + return "proto2"; +} + + class SourceLocationCommentPrinter { public: template @@ -3198,13 +3201,11 @@ std::string FileDescriptor::DebugStringWithOptions( SourceLocationCommentPrinter syntax_comment(this, path, "", debug_string_options); syntax_comment.AddPreComment(&contents); - if (FileDescriptorLegacy(this).syntax() == - FileDescriptorLegacy::SYNTAX_EDITIONS) { - absl::SubstituteAndAppend(&contents, "edition = \"$0\";\n\n", edition()); - } else { + if (IsLegacyEdition(this)) { absl::SubstituteAndAppend(&contents, "syntax = \"$0\";\n\n", - FileDescriptorLegacy::SyntaxName( - FileDescriptorLegacy(this).syntax())); + GetLegacySyntaxName(this)); + } else { + absl::SubstituteAndAppend(&contents, "edition = \"$0\";\n\n", edition()); } syntax_comment.AddPostComment(&contents); } @@ -3477,13 +3478,11 @@ void FieldDescriptor::DebugString( // Label is omitted for maps, oneof, and plain proto3 fields. if (is_map() || real_containing_oneof() || - (is_optional() && !FieldDescriptorLegacy(this).has_optional_keyword())) { + (is_optional() && !has_optional_keyword())) { label.clear(); } // Label is omitted for optional and required fields under editions. - if ((is_optional() || is_required()) && - FileDescriptorLegacy(file()).syntax() == - FileDescriptorLegacy::SYNTAX_EDITIONS) { + if ((is_optional() || is_required()) && !IsLegacyEdition(this)) { label.clear(); } @@ -3788,6 +3787,11 @@ bool FieldDescriptor::legacy_enum_field_treated_as_closed() const { enum_type()->is_closed()); } +bool FieldDescriptor::has_optional_keyword() const { + return proto3_optional_ || (file()->edition() == Edition::EDITION_PROTO2 && + is_optional() && !containing_oneof()); +} + // Location methods =============================================== bool FileDescriptor::GetSourceLocation(const std::vector& path, @@ -4257,7 +4261,6 @@ class DescriptorBuilder { void CheckFieldJsonNameUniqueness(const std::string& message_name, const DescriptorProto& message, const Descriptor* descriptor, - FileDescriptorLegacy::Syntax syntax, bool use_custom_names); void CheckEnumValueUniqueness(const EnumDescriptorProto& proto, const EnumDescriptor* result); @@ -4546,21 +4549,51 @@ const FileDescriptor* DescriptorPool::BuildFileFromDatabase( if (tables_->known_bad_files_.contains(proto.name())) { return nullptr; } - const FileDescriptor* result = - DescriptorBuilder::New(this, tables_.get(), default_error_collector_) - ->BuildFile(proto); + const FileDescriptor* result; + const auto build_file = [&] { + result = + DescriptorBuilder::New(this, tables_.get(), default_error_collector_) + ->BuildFile(proto); + }; + if (dispatcher_ != nullptr) { + (*dispatcher_)(build_file); + } else { + build_file(); + } if (result == nullptr) { tables_->known_bad_files_.insert(proto.name()); } return result; } -void DescriptorPool::SetFeatureSetDefaults(FeatureSetDefaults spec) { - ABSL_CHECK(!build_started_) - << "Feature set defaults can't be changed once the pool has started " - "building."; +absl::Status DescriptorPool::SetFeatureSetDefaults(FeatureSetDefaults spec) { + if (build_started_) { + return absl::FailedPreconditionError( + "Feature set defaults can't be changed once the pool has started " + "building."); + } + if (spec.minimum_edition() > spec.maximum_edition()) { + return absl::InvalidArgumentError( + absl::StrCat("Invalid edition range ", spec.minimum_edition(), " to ", + spec.maximum_edition(), ".")); + } + Edition prev_edition = EDITION_UNKNOWN; + for (const auto& edition_default : spec.defaults()) { + if (edition_default.edition() == EDITION_UNKNOWN) { + return absl::InvalidArgumentError(absl::StrCat( + "Invalid edition ", edition_default.edition(), " specified.")); + } + if (edition_default.edition() <= prev_edition) { + return absl::InvalidArgumentError(absl::StrCat( + "Feature set defaults are not strictly increasing. Edition ", + prev_edition, " is greater than or equal to edition ", + edition_default.edition(), ".")); + } + prev_edition = edition_default.edition(); + } feature_set_defaults_spec_ = absl::make_unique(std::move(spec)); + return absl::OkStatus(); } DescriptorBuilder::DescriptorBuilder( @@ -4577,7 +4610,14 @@ DescriptorBuilder::DescriptorBuilder( // have to avoid registering these pre-main, because we need to ensure that // the linker --gc-sections step can strip out the full runtime if it is // unused. - pb::cpp.LazyRegister(); + PROTOBUF_UNUSED static std::true_type lazy_register = + (internal::ExtensionSet::RegisterMessageExtension( + &FeatureSet::default_instance(), pb::cpp.number(), + FieldDescriptor::TYPE_MESSAGE, false, false, + &pb::CppFeatures::default_instance(), + nullptr, + internal::LazyAnnotation::kUndefined), + std::true_type{}); } DescriptorBuilder::~DescriptorBuilder() {} @@ -5020,7 +5060,6 @@ FileDescriptor* DescriptorPool::NewPlaceholderFileWithMutexHeld( placeholder->tables_ = &FileDescriptorTables::GetEmptyInstance(); placeholder->source_code_info_ = &SourceCodeInfo::default_instance(); placeholder->is_placeholder_ = true; - placeholder->syntax_ = FileDescriptorLegacy::SYNTAX_UNKNOWN; placeholder->finished_building_ = true; // All other fields are zero or nullptr. @@ -5242,14 +5281,12 @@ typename DescriptorT::OptionsType* DescriptorBuilder::AllocateOptionsImpl( template static void InferLegacyProtoFeatures(const ProtoT& proto, - const OptionsT& options, - FileDescriptorLegacy::Syntax syntax, + const OptionsT& options, Edition edition, FeatureSet& features) {} static void InferLegacyProtoFeatures(const FieldDescriptorProto& proto, const FieldOptions& options, - FileDescriptorLegacy::Syntax syntax, - FeatureSet& features) { + Edition edition, FeatureSet& features) { if (proto.label() == FieldDescriptorProto::LABEL_REQUIRED) { features.set_field_presence(FeatureSet::LEGACY_REQUIRED); } @@ -5259,25 +5296,13 @@ static void InferLegacyProtoFeatures(const FieldDescriptorProto& proto, if (options.packed()) { features.set_repeated_field_encoding(FeatureSet::PACKED); } - if (syntax == FileDescriptorLegacy::SYNTAX_PROTO3) { + if (edition == Edition::EDITION_PROTO3) { if (options.has_packed() && !options.packed()) { features.set_repeated_field_encoding(FeatureSet::EXPANDED); } } } -template -FileDescriptorLegacy::Syntax GetDescriptorSyntax( - const DescriptorT* descriptor) { - return FileDescriptorLegacy(descriptor->file()).syntax(); -} - -template <> -FileDescriptorLegacy::Syntax GetDescriptorSyntax( - const FileDescriptor* descriptor) { - return FileDescriptorLegacy(descriptor).syntax(); -} - template void DescriptorBuilder::ResolveFeaturesImpl( const typename DescriptorT::Proto& proto, DescriptorT* descriptor, @@ -5301,13 +5326,12 @@ void DescriptorBuilder::ResolveFeaturesImpl( FeatureSet base_features = *descriptor->proto_features_; // Handle feature inference from proto2/proto3. - if (GetDescriptorSyntax(descriptor) != - FileDescriptorLegacy::SYNTAX_EDITIONS) { + if (IsLegacyEdition(descriptor)) { if (descriptor->proto_features_ != &FeatureSet::default_instance()) { AddError(descriptor->name(), proto, error_location, "Features are only valid under editions."); } - InferLegacyProtoFeatures(proto, *options, GetDescriptorSyntax(descriptor), + InferLegacyProtoFeatures(proto, *options, GetDescriptorEdition(descriptor), base_features); } @@ -5423,13 +5447,9 @@ PROTOBUF_NOINLINE static bool ExistingFileMatchesProto( const FileDescriptor* existing_file, const FileDescriptorProto& proto) { FileDescriptorProto existing_proto; existing_file->CopyTo(&existing_proto); - // TODO: Remove it when CopyTo supports copying syntax params when - // syntax="proto2". - if (FileDescriptorLegacy(existing_file).syntax() == - FileDescriptorLegacy::Syntax::SYNTAX_PROTO2 && + if (existing_file->edition() == Edition::EDITION_PROTO2 && proto.has_syntax()) { - existing_proto.set_syntax(FileDescriptorLegacy::SyntaxName( - FileDescriptorLegacy(existing_file).syntax())); + existing_proto.set_syntax("proto2"); } return existing_proto.SerializeAsString() == proto.SerializeAsString(); @@ -5651,16 +5671,12 @@ FileDescriptor* DescriptorBuilder::BuildFileImpl( // TODO: Report error when the syntax is empty after all the protos // have added the syntax statement. if (proto.syntax().empty() || proto.syntax() == "proto2") { - file_->syntax_ = FileDescriptorLegacy::SYNTAX_PROTO2; file_->edition_ = Edition::EDITION_PROTO2; } else if (proto.syntax() == "proto3") { - file_->syntax_ = FileDescriptorLegacy::SYNTAX_PROTO3; file_->edition_ = Edition::EDITION_PROTO3; } else if (proto.syntax() == "editions") { - file_->syntax_ = FileDescriptorLegacy::SYNTAX_EDITIONS; file_->edition_ = proto.edition(); } else { - file_->syntax_ = FileDescriptorLegacy::SYNTAX_UNKNOWN; file_->edition_ = Edition::EDITION_UNKNOWN; AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, [&] { return absl::StrCat("Unrecognized syntax: ", proto.syntax()); @@ -6174,21 +6190,19 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, void DescriptorBuilder::CheckFieldJsonNameUniqueness( const DescriptorProto& proto, const Descriptor* result) { - FileDescriptorLegacy::Syntax syntax = - FileDescriptorLegacy(result->file()).syntax(); std::string message_name = result->full_name(); if (pool_->deprecated_legacy_json_field_conflicts_ || IsLegacyJsonFieldConflictEnabled(result->options())) { - if (syntax == FileDescriptorLegacy::Syntax::SYNTAX_PROTO3) { + if (result->file()->edition() == Edition::EDITION_PROTO3) { // Only check default JSON names for conflicts in proto3. This is legacy // behavior that will be removed in a later version. - CheckFieldJsonNameUniqueness(message_name, proto, result, syntax, false); + CheckFieldJsonNameUniqueness(message_name, proto, result, false); } } else { // Check both with and without taking json_name into consideration. This is // needed for field masks, which don't use json_name. - CheckFieldJsonNameUniqueness(message_name, proto, result, syntax, false); - CheckFieldJsonNameUniqueness(message_name, proto, result, syntax, true); + CheckFieldJsonNameUniqueness(message_name, proto, result, false); + CheckFieldJsonNameUniqueness(message_name, proto, result, true); } } @@ -6219,8 +6233,7 @@ bool JsonNameLooksLikeExtension(std::string name) { void DescriptorBuilder::CheckFieldJsonNameUniqueness( const std::string& message_name, const DescriptorProto& message, - const Descriptor* descriptor, FileDescriptorLegacy::Syntax syntax, - bool use_custom_names) { + const Descriptor* descriptor, bool use_custom_names) { absl::flat_hash_map name_to_field; for (const FieldDescriptorProto& field : message.field()) { JsonNameDetails details = GetJsonNameDetails(&field, use_custom_names); @@ -6304,9 +6317,7 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, result->is_oneof_ = false; result->proto3_optional_ = proto.proto3_optional(); - if (proto.proto3_optional() && - FileDescriptorLegacy(file_).syntax() != - FileDescriptorLegacy::Syntax::SYNTAX_PROTO3) { + if (proto.proto3_optional() && file_->edition() != Edition::EDITION_PROTO3) { AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, [&] { return absl::StrCat( @@ -6706,8 +6717,7 @@ void DescriptorBuilder::CheckEnumValueUniqueness( // compatibility we issue only a warning for proto2. if ((pool_->deprecated_legacy_json_field_conflicts_ || IsLegacyJsonFieldConflictEnabled(result->options())) && - FileDescriptorLegacy(result->file()).syntax() == - FileDescriptorLegacy::Syntax::SYNTAX_PROTO2) { + result->file()->edition() == Edition::EDITION_PROTO2) { AddWarning(value->full_name(), proto.value(i), DescriptorPool::ErrorCollector::NAME, make_error); continue; @@ -7054,7 +7064,7 @@ void DescriptorBuilder::CrossLinkMessage(Descriptor* message, const FieldDescriptor* field = message->field(i); if (field->proto3_optional_) { if (!field->containing_oneof() || - !OneofDescriptorLegacy(field->containing_oneof()).is_synthetic()) { + !field->containing_oneof()->is_synthetic()) { AddError(message->full_name(), proto.field(i), DescriptorPool::ErrorCollector::OTHER, "Fields with proto3_optional set must be " @@ -7066,8 +7076,7 @@ void DescriptorBuilder::CrossLinkMessage(Descriptor* message, // Synthetic oneofs must be last. int first_synthetic = -1; for (int i = 0; i < message->oneof_decl_count(); i++) { - const OneofDescriptor* oneof = message->oneof_decl(i); - if (OneofDescriptorLegacy(oneof).is_synthetic()) { + if (message->oneof_decl(i)->is_synthetic()) { if (first_synthetic == -1) { first_synthetic = i; } @@ -7631,8 +7640,7 @@ void DescriptorBuilder::ValidateOptions(const FileDescriptor* file, } } } - if (FileDescriptorLegacy(file).syntax() == - FileDescriptorLegacy::Syntax::SYNTAX_PROTO3) { + if (file->edition() == Edition::EDITION_PROTO3) { ValidateProto3(file, proto); } } @@ -7688,17 +7696,13 @@ void DescriptorBuilder::ValidateProto3Field(const FieldDescriptor* field, "Explicit default values are not allowed in proto3."); } if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM && - field->enum_type() && - FileDescriptorLegacy(field->enum_type()->file()).syntax() != - FileDescriptorLegacy::Syntax::SYNTAX_PROTO3 && - FileDescriptorLegacy(field->enum_type()->file()).syntax() != - FileDescriptorLegacy::Syntax::SYNTAX_UNKNOWN) { - // Proto3 messages can only use Proto3 enum types; otherwise we can't + field->enum_type() && field->enum_type()->is_closed()) { + // Proto3 messages can only use open enum types; otherwise we can't // guarantee that the default value is zero. AddError( field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, [&] { return absl::StrCat("Enum type \"", field->enum_type()->full_name(), - "\" is not a proto3 enum, but is used in \"", + "\" is not an open enum, but is used in \"", field->containing_type()->full_name(), "\" which is a proto3 message type."); }); @@ -7878,8 +7882,7 @@ static bool IsStringMapType(const FieldDescriptor& field) { void DescriptorBuilder::ValidateFileFeatures(const FileDescriptor* file, const FileDescriptorProto& proto) { // Rely on our legacy validation for proto2/proto3 files. - if (FileDescriptorLegacy(file).syntax() != - FileDescriptorLegacy::SYNTAX_EDITIONS) { + if (IsLegacyEdition(file)) { return; } @@ -7898,8 +7901,7 @@ void DescriptorBuilder::ValidateFileFeatures(const FileDescriptor* file, void DescriptorBuilder::ValidateFieldFeatures( const FieldDescriptor* field, const FieldDescriptorProto& proto) { // Rely on our legacy validation for proto2/proto3 files. - if (FileDescriptorLegacy(field->file()).syntax() != - FileDescriptorLegacy::SYNTAX_EDITIONS) { + if (field->file()->edition() < Edition::EDITION_2023) { return; } @@ -9555,13 +9557,18 @@ static bool IsVerifyUtf8(const FieldDescriptor* field, bool is_lite) { // Which level of UTF-8 enforcemant is placed on this file. Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field, bool is_lite) { - if (IsStrictUtf8(field)) { - return Utf8CheckMode::kStrict; - } else if (IsVerifyUtf8(field, is_lite)) { - return Utf8CheckMode::kVerify; - } else { - return Utf8CheckMode::kNone; - } + if (field->type() == FieldDescriptor::TYPE_STRING || + (field->is_map() && (field->message_type()->map_key()->type() == + FieldDescriptor::TYPE_STRING || + field->message_type()->map_value()->type() == + FieldDescriptor::TYPE_STRING))) { + if (IsStrictUtf8(field)) { + return Utf8CheckMode::kStrict; + } else if (IsVerifyUtf8(field, is_lite)) { + return Utf8CheckMode::kVerify; + } + } + return Utf8CheckMode::kNone; } bool IsLazilyInitializedFile(absl::string_view filename) { diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index ff178c31c9..dfb71df1f2 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "google/protobuf/stubs/common.h" @@ -43,12 +44,15 @@ #include "absl/base/call_once.h" #include "absl/container/btree_map.h" #include "absl/container/flat_hash_map.h" +#include "absl/functional/any_invocable.h" +#include "absl/functional/function_ref.h" #include "absl/log/absl_check.h" #include "absl/log/absl_log.h" #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" #include "absl/types/optional.h" +#include "google/protobuf/descriptor_lite.h" #include "google/protobuf/extension_set.h" #include "google/protobuf/port.h" @@ -493,10 +497,7 @@ class PROTOBUF_EXPORT Descriptor : private internal::SymbolBase { // Never nullptr. const Descriptor* containing_type() const { return containing_type_; } -#ifdef PROTOBUF_FUTURE_EXTENSION_RANGE_CLASS - private: -#endif int start_; int end_; const ExtensionRangeOptions* options_; @@ -731,7 +732,8 @@ PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(Descriptor, 152); // - Given a DescriptorPool, call DescriptorPool::FindExtensionByNumber() or // DescriptorPool::FindExtensionByPrintableName(). // Use DescriptorPool to construct your own descriptors. -class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase { +class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase, + public internal::FieldDescriptorLite { public: typedef FieldDescriptorProto Proto; @@ -742,64 +744,67 @@ class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase { // Identifies a field type. 0 is reserved for errors. The order is weird // for historical reasons. Types 12 and up are new in proto2. - enum Type { - TYPE_DOUBLE = 1, // double, exactly eight bytes on the wire. - TYPE_FLOAT = 2, // float, exactly four bytes on the wire. - TYPE_INT64 = 3, // int64, varint on the wire. Negative numbers - // take 10 bytes. Use TYPE_SINT64 if negative - // values are likely. - TYPE_UINT64 = 4, // uint64, varint on the wire. - TYPE_INT32 = 5, // int32, varint on the wire. Negative numbers - // take 10 bytes. Use TYPE_SINT32 if negative - // values are likely. - TYPE_FIXED64 = 6, // uint64, exactly eight bytes on the wire. - TYPE_FIXED32 = 7, // uint32, exactly four bytes on the wire. - TYPE_BOOL = 8, // bool, varint on the wire. - TYPE_STRING = 9, // UTF-8 text. - TYPE_GROUP = 10, // Tag-delimited message. Deprecated. - TYPE_MESSAGE = 11, // Length-delimited message. - - TYPE_BYTES = 12, // Arbitrary byte array. - TYPE_UINT32 = 13, // uint32, varint on the wire - TYPE_ENUM = 14, // Enum, varint on the wire - TYPE_SFIXED32 = 15, // int32, exactly four bytes on the wire - TYPE_SFIXED64 = 16, // int64, exactly eight bytes on the wire - TYPE_SINT32 = 17, // int32, ZigZag-encoded varint on the wire - TYPE_SINT64 = 18, // int64, ZigZag-encoded varint on the wire - - MAX_TYPE = 18, // Constant useful for defining lookup tables - // indexed by Type. - }; + // Inherited from FieldDescriptorLite: + // enum Type { + // TYPE_DOUBLE = 1, // double, exactly eight bytes on the wire. + // TYPE_FLOAT = 2, // float, exactly four bytes on the wire. + // TYPE_INT64 = 3, // int64, varint on the wire. Negative numbers + // // take 10 bytes. Use TYPE_SINT64 if negative + // // values are likely. + // TYPE_UINT64 = 4, // uint64, varint on the wire. + // TYPE_INT32 = 5, // int32, varint on the wire. Negative numbers + // // take 10 bytes. Use TYPE_SINT32 if negative + // // values are likely. + // TYPE_FIXED64 = 6, // uint64, exactly eight bytes on the wire. + // TYPE_FIXED32 = 7, // uint32, exactly four bytes on the wire. + // TYPE_BOOL = 8, // bool, varint on the wire. + // TYPE_STRING = 9, // UTF-8 text. + // TYPE_GROUP = 10, // Tag-delimited message. Deprecated. + // TYPE_MESSAGE = 11, // Length-delimited message. + + // TYPE_BYTES = 12, // Arbitrary byte array. + // TYPE_UINT32 = 13, // uint32, varint on the wire + // TYPE_ENUM = 14, // Enum, varint on the wire + // TYPE_SFIXED32 = 15, // int32, exactly four bytes on the wire + // TYPE_SFIXED64 = 16, // int64, exactly eight bytes on the wire + // TYPE_SINT32 = 17, // int32, ZigZag-encoded varint on the wire + // TYPE_SINT64 = 18, // int64, ZigZag-encoded varint on the wire + + // MAX_TYPE = 18, // Constant useful for defining lookup tables + // // indexed by Type. + // }; // Specifies the C++ data type used to represent the field. There is a // fixed mapping from Type to CppType where each Type maps to exactly one // CppType. 0 is reserved for errors. - enum CppType { - CPPTYPE_INT32 = 1, // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32 - CPPTYPE_INT64 = 2, // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64 - CPPTYPE_UINT32 = 3, // TYPE_UINT32, TYPE_FIXED32 - CPPTYPE_UINT64 = 4, // TYPE_UINT64, TYPE_FIXED64 - CPPTYPE_DOUBLE = 5, // TYPE_DOUBLE - CPPTYPE_FLOAT = 6, // TYPE_FLOAT - CPPTYPE_BOOL = 7, // TYPE_BOOL - CPPTYPE_ENUM = 8, // TYPE_ENUM - CPPTYPE_STRING = 9, // TYPE_STRING, TYPE_BYTES - CPPTYPE_MESSAGE = 10, // TYPE_MESSAGE, TYPE_GROUP - - MAX_CPPTYPE = 10, // Constant useful for defining lookup tables - // indexed by CppType. - }; + // Inherited from FieldDescriptorLite: + // enum CppType { + // CPPTYPE_INT32 = 1, // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32 + // CPPTYPE_INT64 = 2, // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64 + // CPPTYPE_UINT32 = 3, // TYPE_UINT32, TYPE_FIXED32 + // CPPTYPE_UINT64 = 4, // TYPE_UINT64, TYPE_FIXED64 + // CPPTYPE_DOUBLE = 5, // TYPE_DOUBLE + // CPPTYPE_FLOAT = 6, // TYPE_FLOAT + // CPPTYPE_BOOL = 7, // TYPE_BOOL + // CPPTYPE_ENUM = 8, // TYPE_ENUM + // CPPTYPE_STRING = 9, // TYPE_STRING, TYPE_BYTES + // CPPTYPE_MESSAGE = 10, // TYPE_MESSAGE, TYPE_GROUP + + // MAX_CPPTYPE = 10, // Constant useful for defining lookup tables + // // indexed by CppType. + // }; // Identifies whether the field is optional, required, or repeated. 0 is // reserved for errors. - enum Label { - LABEL_OPTIONAL = 1, // optional - LABEL_REQUIRED = 2, // required - LABEL_REPEATED = 3, // repeated + // Inherited from FieldDescriptorLite: + // enum Label { + // LABEL_OPTIONAL = 1, // optional + // LABEL_REQUIRED = 2, // required + // LABEL_REPEATED = 3, // repeated - MAX_LABEL = 3, // Constant useful for defining lookup tables - // indexed by Label. - }; + // MAX_LABEL = 3, // Constant useful for defining lookup tables + // // indexed by Label. + // }; // Valid field numbers are positive integers up to kMaxNumber. static const int kMaxNumber = (1 << 29) - 1; @@ -1028,17 +1033,10 @@ class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase { friend class Reflection; friend class FieldDescriptorLegacy; - - public: - ABSL_DEPRECATED( - "Syntax is deprecated in favor of editions, please use " - "FieldDescriptor::has_presence instead.") // Returns true if this field was syntactically written with "optional" in the // .proto file. Excludes singular proto3 fields that do not have a label. bool has_optional_keyword() const; - private: - // Get the merged features that apply to this field. These are specified in // the .proto file through the feature options in the message definition. // Allowed features are defined by Features in descriptor.proto, along with @@ -1211,17 +1209,10 @@ class PROTOBUF_EXPORT OneofDescriptor : private internal::SymbolBase { friend class compiler::cpp::Formatter; friend class OneofDescriptorLegacy; - - public: - ABSL_DEPRECATED( - "Syntax is deprecated in favor of editions, please use " - "real_oneof_decl_count for now instead of is_synthetic.") // Returns whether this oneof was inserted by the compiler to wrap a proto3 // optional field. If this returns true, code generators should *not* emit it. bool is_synthetic() const; - private: - // Get the merged features that apply to this oneof. These are specified in // the .proto file through the feature options in the oneof definition. // Allowed features are defined by Features in descriptor.proto, along with @@ -1256,6 +1247,7 @@ class PROTOBUF_EXPORT OneofDescriptor : private internal::SymbolBase { friend class DescriptorBuilder; friend class Descriptor; friend class FieldDescriptor; + friend class Reflection; }; PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(OneofDescriptor, 56); @@ -1861,46 +1853,9 @@ class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase { // descriptor.proto, and any available extensions of that message. const FileOptions& options() const; - - private: - // With the upcoming release of editions, syntax should not be used for - // business logic. Instead, the various feature helpers defined in this file - // should be used to query more targeted behaviors. For example: - // has_presence, is_closed, requires_utf8_validation. - enum - ABSL_DEPRECATED( - "Syntax is deprecated in favor of editions. Please use targeted " - "feature helpers instead (e.g. has_presence, is_packed, " - "requires_utf8_validation, etc).") - Syntax -#ifndef SWIG - : int -#endif // !SWIG - { - SYNTAX_UNKNOWN = 0, - SYNTAX_PROTO2 = 2, - SYNTAX_PROTO3 = 3, - SYNTAX_EDITIONS = 99, - }; - PROTOBUF_IGNORE_DEPRECATION_START - ABSL_DEPRECATED( - "Syntax is deprecated in favor of editions. Please use targeted " - "feature helpers instead (e.g. has_presence, is_packed, " - "requires_utf8_validation, etc).") - Syntax syntax() const; - PROTOBUF_IGNORE_DEPRECATION_STOP - - // Define a visibility-restricted wrapper for internal use until the migration - // is complete. - friend class FileDescriptorLegacy; - - PROTOBUF_IGNORE_DEPRECATION_START - ABSL_DEPRECATED("Syntax is deprecated in favor of editions") - static const char* SyntaxName(Syntax syntax); - PROTOBUF_IGNORE_DEPRECATION_STOP - public: - // Returns EDITION_UNKNOWN if syntax() is not SYNTAX_EDITIONS. + // Returns edition of this file. For legacy proto2/proto3 files, special + // EDITION_PROTO2 and EDITION_PROTO3 values are used. Edition edition() const; // Find a top-level message type by name (not full_name). Returns nullptr if @@ -1936,7 +1891,7 @@ class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase { // Fill the json_name field of FieldDescriptorProto for all fields. Can only // be called after CopyTo(). void CopyJsonNameTo(FileDescriptorProto* proto) const; - // Fills in the file-level settings of this file (e.g. syntax, package, + // Fills in the file-level settings of this file (e.g. edition, package, // file options) to `proto`. void CopyHeadingTo(FileDescriptorProto* proto) const; @@ -1978,8 +1933,6 @@ class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase { // that type accessor functions that can possibly build a dependent file // aren't called during the process of building the file. bool finished_building_; - // Actually a `Syntax` but stored as uint8_t to save space. - uint8_t syntax_; // This one is here to fill the padding. int extension_count_; @@ -2285,7 +2238,7 @@ class PROTOBUF_EXPORT DescriptorPool { // called, these defaults will be used instead. // FeatureSetDefaults includes a minimum/maximum supported edition, which will // be enforced while building proto files. - void SetFeatureSetDefaults(FeatureSetDefaults spec); + absl::Status SetFeatureSetDefaults(FeatureSetDefaults spec); // Toggles enforcement of extension declarations. // This enforcement is disabled by default because it requires full @@ -2294,6 +2247,20 @@ class PROTOBUF_EXPORT DescriptorPool { void EnforceExtensionDeclarations(bool enforce) { enforce_extension_declarations_ = enforce; } + +#ifndef SWIG + // Dispatch recursive builds to a callback that may stick them onto a separate + // thread. This is primarily to avoid stack overflows on untrusted inputs. + // The dispatcher must always synchronously execute the provided callback. + // Asynchronous execution is undefined behavior. + void SetRecursiveBuildDispatcher( + absl::AnyInvocable) const> dispatcher) { + dispatcher_ = std::make_unique< + absl::AnyInvocable) const>>( + std::move(dispatcher)); + } +#endif // SWIG + // Internal stuff -------------------------------------------------- // These methods MUST NOT be called from outside the proto2 library. // These methods may contain hidden pitfalls and may be removed in a @@ -2455,6 +2422,12 @@ class PROTOBUF_EXPORT DescriptorPool { ErrorCollector* default_error_collector_; const DescriptorPool* underlay_; +#ifndef SWIG + // Dispatcher for recursive calls during builds. + std::unique_ptr) const>> + dispatcher_; +#endif // SWIG + // This class contains a lot of hash maps with complicated types that // we'd like to keep out of the header. class Tables; @@ -2721,19 +2694,9 @@ inline bool FieldDescriptor::is_map() const { return type() == TYPE_MESSAGE && is_map_message_type(); } -inline bool FieldDescriptor::has_optional_keyword() const { - PROTOBUF_IGNORE_DEPRECATION_START - return proto3_optional_ || - (file()->syntax() == FileDescriptor::SYNTAX_PROTO2 && is_optional() && - !containing_oneof()); - PROTOBUF_IGNORE_DEPRECATION_STOP -} - inline const OneofDescriptor* FieldDescriptor::real_containing_oneof() const { - PROTOBUF_IGNORE_DEPRECATION_START auto* oneof = containing_oneof(); return oneof && !oneof->is_synthetic() ? oneof : nullptr; - PROTOBUF_IGNORE_DEPRECATION_STOP } // To save space, index() is computed by looking at the descriptor's position @@ -2840,12 +2803,6 @@ inline const FileDescriptor* FileDescriptor::weak_dependency(int index) const { return dependency(weak_dependencies_[index]); } -PROTOBUF_IGNORE_DEPRECATION_START -inline FileDescriptor::Syntax FileDescriptor::syntax() const { - return static_cast(syntax_); -} -PROTOBUF_IGNORE_DEPRECATION_STOP - namespace internal { // FieldRange(desc) provides an iterable range for the fields of a diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index ae02aa9a2d..269a8dc448 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -1,5 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/descriptor.proto +// Protobuf C++ Version: 4.26.0-dev #include "google/protobuf/descriptor.pb.h" @@ -1694,218 +1695,219 @@ const char descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto[] AB "\r\n\005start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\0227\n\007options\030\003" " \001(\0132&.google.protobuf.ExtensionRangeOpt" "ions\032+\n\rReservedRange\022\r\n\005start\030\001 \001(\005\022\013\n\003" - "end\030\002 \001(\005\"\340\003\n\025ExtensionRangeOptions\022C\n\024u" + "end\030\002 \001(\005\"\345\003\n\025ExtensionRangeOptions\022C\n\024u" "ninterpreted_option\030\347\007 \003(\0132$.google.prot" "obuf.UninterpretedOption\022L\n\013declaration\030" "\002 \003(\01322.google.protobuf.ExtensionRangeOp" "tions.DeclarationB\003\210\001\002\022-\n\010features\0302 \001(\013" - "2\033.google.protobuf.FeatureSet\022Z\n\014verific" + "2\033.google.protobuf.FeatureSet\022_\n\014verific" "ation\030\003 \001(\01628.google.protobuf.ExtensionR" "angeOptions.VerificationState:\nUNVERIFIE" - "D\032h\n\013Declaration\022\016\n\006number\030\001 \001(\005\022\021\n\tfull" - "_name\030\002 \001(\t\022\014\n\004type\030\003 \001(\t\022\020\n\010reserved\030\005 " - "\001(\010\022\020\n\010repeated\030\006 \001(\010J\004\010\004\020\005\"4\n\021Verificat" - "ionState\022\017\n\013DECLARATION\020\000\022\016\n\nUNVERIFIED\020" - "\001*\t\010\350\007\020\200\200\200\200\002\"\325\005\n\024FieldDescriptorProto\022\014\n" - "\004name\030\001 \001(\t\022\016\n\006number\030\003 \001(\005\022:\n\005label\030\004 \001" - "(\0162+.google.protobuf.FieldDescriptorProt" - "o.Label\0228\n\004type\030\005 \001(\0162*.google.protobuf." - "FieldDescriptorProto.Type\022\021\n\ttype_name\030\006" - " \001(\t\022\020\n\010extendee\030\002 \001(\t\022\025\n\rdefault_value\030" - "\007 \001(\t\022\023\n\013oneof_index\030\t \001(\005\022\021\n\tjson_name\030" - "\n \001(\t\022.\n\007options\030\010 \001(\0132\035.google.protobuf" - ".FieldOptions\022\027\n\017proto3_optional\030\021 \001(\010\"\266" - "\002\n\004Type\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002" - "\022\016\n\nTYPE_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYP" - "E_INT32\020\005\022\020\n\014TYPE_FIXED64\020\006\022\020\n\014TYPE_FIXE" - "D32\020\007\022\r\n\tTYPE_BOOL\020\010\022\017\n\013TYPE_STRING\020\t\022\016\n" - "\nTYPE_GROUP\020\n\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_" - "BYTES\020\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE_ENUM\020\016\022" - "\021\n\rTYPE_SFIXED32\020\017\022\021\n\rTYPE_SFIXED64\020\020\022\017\n" - "\013TYPE_SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\"C\n\005Label" - "\022\022\n\016LABEL_OPTIONAL\020\001\022\022\n\016LABEL_REPEATED\020\003" - "\022\022\n\016LABEL_REQUIRED\020\002\"T\n\024OneofDescriptorP" - "roto\022\014\n\004name\030\001 \001(\t\022.\n\007options\030\002 \001(\0132\035.go" - "ogle.protobuf.OneofOptions\"\244\002\n\023EnumDescr" - "iptorProto\022\014\n\004name\030\001 \001(\t\0228\n\005value\030\002 \003(\0132" - ").google.protobuf.EnumValueDescriptorPro" - "to\022-\n\007options\030\003 \001(\0132\034.google.protobuf.En" - "umOptions\022N\n\016reserved_range\030\004 \003(\01326.goog" - "le.protobuf.EnumDescriptorProto.EnumRese" - "rvedRange\022\025\n\rreserved_name\030\005 \003(\t\032/\n\021Enum" - "ReservedRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end\030\002 \001(" - "\005\"l\n\030EnumValueDescriptorProto\022\014\n\004name\030\001 " - "\001(\t\022\016\n\006number\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.g" - "oogle.protobuf.EnumValueOptions\"\220\001\n\026Serv" - "iceDescriptorProto\022\014\n\004name\030\001 \001(\t\0226\n\006meth" - "od\030\002 \003(\0132&.google.protobuf.MethodDescrip" - "torProto\0220\n\007options\030\003 \001(\0132\037.google.proto" - "buf.ServiceOptions\"\301\001\n\025MethodDescriptorP" - "roto\022\014\n\004name\030\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t\022\023" - "\n\013output_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.g" - "oogle.protobuf.MethodOptions\022\037\n\020client_s" - "treaming\030\005 \001(\010:\005false\022\037\n\020server_streamin" - "g\030\006 \001(\010:\005false\"\324\006\n\013FileOptions\022\024\n\014java_p" - "ackage\030\001 \001(\t\022\034\n\024java_outer_classname\030\010 \001" - "(\t\022\"\n\023java_multiple_files\030\n \001(\010:\005false\022)" - "\n\035java_generate_equals_and_hash\030\024 \001(\010B\002\030" - "\001\022%\n\026java_string_check_utf8\030\033 \001(\010:\005false" - "\022F\n\014optimize_for\030\t \001(\0162).google.protobuf" - ".FileOptions.OptimizeMode:\005SPEED\022\022\n\ngo_p" - "ackage\030\013 \001(\t\022\"\n\023cc_generic_services\030\020 \001(" - "\010:\005false\022$\n\025java_generic_services\030\021 \001(\010:" - "\005false\022\"\n\023py_generic_services\030\022 \001(\010:\005fal" - "se\022#\n\024php_generic_services\030* \001(\010:\005false\022" - "\031\n\ndeprecated\030\027 \001(\010:\005false\022\036\n\020cc_enable_" - "arenas\030\037 \001(\010:\004true\022\031\n\021objc_class_prefix\030" - "$ \001(\t\022\030\n\020csharp_namespace\030% \001(\t\022\024\n\014swift" - "_prefix\030\' \001(\t\022\030\n\020php_class_prefix\030( \001(\t\022" - "\025\n\rphp_namespace\030) \001(\t\022\036\n\026php_metadata_n" - "amespace\030, \001(\t\022\024\n\014ruby_package\030- \001(\t\022-\n\010" - "features\0302 \001(\0132\033.google.protobuf.Feature" - "Set\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goo" - "gle.protobuf.UninterpretedOption\":\n\014Opti" - "mizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LI" - "TE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002J\004\010&\020\'\"\347\002\n\016Messag" - "eOptions\022&\n\027message_set_wire_format\030\001 \001(" - "\010:\005false\022.\n\037no_standard_descriptor_acces" - "sor\030\002 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005fa" - "lse\022\021\n\tmap_entry\030\007 \001(\010\0222\n&deprecated_leg" - "acy_json_field_conflicts\030\013 \001(\010B\002\030\001\022-\n\010fe" - "atures\030\014 \001(\0132\033.google.protobuf.FeatureSe" - "t\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.googl" + "DB\003\210\001\002\032h\n\013Declaration\022\016\n\006number\030\001 \001(\005\022\021\n" + "\tfull_name\030\002 \001(\t\022\014\n\004type\030\003 \001(\t\022\020\n\010reserv" + "ed\030\005 \001(\010\022\020\n\010repeated\030\006 \001(\010J\004\010\004\020\005\"4\n\021Veri" + "ficationState\022\017\n\013DECLARATION\020\000\022\016\n\nUNVERI" + "FIED\020\001*\t\010\350\007\020\200\200\200\200\002\"\325\005\n\024FieldDescriptorPro" + "to\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\003 \001(\005\022:\n\005labe" + "l\030\004 \001(\0162+.google.protobuf.FieldDescripto" + "rProto.Label\0228\n\004type\030\005 \001(\0162*.google.prot" + "obuf.FieldDescriptorProto.Type\022\021\n\ttype_n" + "ame\030\006 \001(\t\022\020\n\010extendee\030\002 \001(\t\022\025\n\rdefault_v" + "alue\030\007 \001(\t\022\023\n\013oneof_index\030\t \001(\005\022\021\n\tjson_" + "name\030\n \001(\t\022.\n\007options\030\010 \001(\0132\035.google.pro" + "tobuf.FieldOptions\022\027\n\017proto3_optional\030\021 " + "\001(\010\"\266\002\n\004Type\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FL" + "OAT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016" + "\n\nTYPE_INT32\020\005\022\020\n\014TYPE_FIXED64\020\006\022\020\n\014TYPE" + "_FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022\017\n\013TYPE_STRING" + "\020\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\n" + "TYPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE_EN" + "UM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rTYPE_SFIXED64" + "\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\"C\n\005" + "Label\022\022\n\016LABEL_OPTIONAL\020\001\022\022\n\016LABEL_REPEA" + "TED\020\003\022\022\n\016LABEL_REQUIRED\020\002\"T\n\024OneofDescri" + "ptorProto\022\014\n\004name\030\001 \001(\t\022.\n\007options\030\002 \001(\013" + "2\035.google.protobuf.OneofOptions\"\244\002\n\023Enum" + "DescriptorProto\022\014\n\004name\030\001 \001(\t\0228\n\005value\030\002" + " \003(\0132).google.protobuf.EnumValueDescript" + "orProto\022-\n\007options\030\003 \001(\0132\034.google.protob" + "uf.EnumOptions\022N\n\016reserved_range\030\004 \003(\01326" + ".google.protobuf.EnumDescriptorProto.Enu" + "mReservedRange\022\025\n\rreserved_name\030\005 \003(\t\032/\n" + "\021EnumReservedRange\022\r\n\005start\030\001 \001(\005\022\013\n\003end" + "\030\002 \001(\005\"l\n\030EnumValueDescriptorProto\022\014\n\004na" + "me\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\0222\n\007options\030\003 \001(" + "\0132!.google.protobuf.EnumValueOptions\"\220\001\n" + "\026ServiceDescriptorProto\022\014\n\004name\030\001 \001(\t\0226\n" + "\006method\030\002 \003(\0132&.google.protobuf.MethodDe" + "scriptorProto\0220\n\007options\030\003 \001(\0132\037.google." + "protobuf.ServiceOptions\"\301\001\n\025MethodDescri" + "ptorProto\022\014\n\004name\030\001 \001(\t\022\022\n\ninput_type\030\002 " + "\001(\t\022\023\n\013output_type\030\003 \001(\t\022/\n\007options\030\004 \001(" + "\0132\036.google.protobuf.MethodOptions\022\037\n\020cli" + "ent_streaming\030\005 \001(\010:\005false\022\037\n\020server_str" + "eaming\030\006 \001(\010:\005false\"\324\006\n\013FileOptions\022\024\n\014j" + "ava_package\030\001 \001(\t\022\034\n\024java_outer_classnam" + "e\030\010 \001(\t\022\"\n\023java_multiple_files\030\n \001(\010:\005fa" + "lse\022)\n\035java_generate_equals_and_hash\030\024 \001" + "(\010B\002\030\001\022%\n\026java_string_check_utf8\030\033 \001(\010:\005" + "false\022F\n\014optimize_for\030\t \001(\0162).google.pro" + "tobuf.FileOptions.OptimizeMode:\005SPEED\022\022\n" + "\ngo_package\030\013 \001(\t\022\"\n\023cc_generic_services" + "\030\020 \001(\010:\005false\022$\n\025java_generic_services\030\021" + " \001(\010:\005false\022\"\n\023py_generic_services\030\022 \001(\010" + ":\005false\022#\n\024php_generic_services\030* \001(\010:\005f" + "alse\022\031\n\ndeprecated\030\027 \001(\010:\005false\022\036\n\020cc_en" + "able_arenas\030\037 \001(\010:\004true\022\031\n\021objc_class_pr" + "efix\030$ \001(\t\022\030\n\020csharp_namespace\030% \001(\t\022\024\n\014" + "swift_prefix\030\' \001(\t\022\030\n\020php_class_prefix\030(" + " \001(\t\022\025\n\rphp_namespace\030) \001(\t\022\036\n\026php_metad" + "ata_namespace\030, \001(\t\022\024\n\014ruby_package\030- \001(" + "\t\022-\n\010features\0302 \001(\0132\033.google.protobuf.Fe" + "atureSet\022C\n\024uninterpreted_option\030\347\007 \003(\0132" + "$.google.protobuf.UninterpretedOption\":\n" + "\014OptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022" + "\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002J\004\010&\020\'\"\347\002\n\016M" + "essageOptions\022&\n\027message_set_wire_format" + "\030\001 \001(\010:\005false\022.\n\037no_standard_descriptor_" + "accessor\030\002 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(" + "\010:\005false\022\021\n\tmap_entry\030\007 \001(\010\0222\n&deprecate" + "d_legacy_json_field_conflicts\030\013 \001(\010B\002\030\001\022" + "-\n\010features\030\014 \001(\0132\033.google.protobuf.Feat" + "ureSet\022C\n\024uninterpreted_option\030\347\007 \003(\0132$." + "google.protobuf.UninterpretedOption*\t\010\350\007" + "\020\200\200\200\200\002J\004\010\004\020\005J\004\010\005\020\006J\004\010\006\020\007J\004\010\010\020\tJ\004\010\t\020\n\"\215\t\n" + "\014FieldOptions\022:\n\005ctype\030\001 \001(\0162#.google.pr" + "otobuf.FieldOptions.CType:\006STRING\022\016\n\006pac" + "ked\030\002 \001(\010\022\?\n\006jstype\030\006 \001(\0162$.google.proto" + "buf.FieldOptions.JSType:\tJS_NORMAL\022\023\n\004la" + "zy\030\005 \001(\010:\005false\022\036\n\017unverified_lazy\030\017 \001(\010" + ":\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\023\n\004we" + "ak\030\n \001(\010:\005false\022\033\n\014debug_redact\030\020 \001(\010:\005f" + "alse\022@\n\tretention\030\021 \001(\0162-.google.protobu" + "f.FieldOptions.OptionRetention\022\?\n\007target" + "s\030\023 \003(\0162..google.protobuf.FieldOptions.O" + "ptionTargetType\022F\n\020edition_defaults\030\024 \003(" + "\0132,.google.protobuf.FieldOptions.Edition" + "Default\022-\n\010features\030\025 \001(\0132\033.google.proto" + "buf.FeatureSet\022C\n\024uninterpreted_option\030\347" + "\007 \003(\0132$.google.protobuf.UninterpretedOpt" + "ion\032J\n\016EditionDefault\022)\n\007edition\030\003 \001(\0162\030" + ".google.protobuf.Edition\022\r\n\005value\030\002 \001(\t\"" + "/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING" + "_PIECE\020\002\"5\n\006JSType\022\r\n\tJS_NORMAL\020\000\022\r\n\tJS_" + "STRING\020\001\022\r\n\tJS_NUMBER\020\002\"U\n\017OptionRetenti" + "on\022\025\n\021RETENTION_UNKNOWN\020\000\022\025\n\021RETENTION_R" + "UNTIME\020\001\022\024\n\020RETENTION_SOURCE\020\002\"\214\002\n\020Optio" + "nTargetType\022\027\n\023TARGET_TYPE_UNKNOWN\020\000\022\024\n\020" + "TARGET_TYPE_FILE\020\001\022\037\n\033TARGET_TYPE_EXTENS" + "ION_RANGE\020\002\022\027\n\023TARGET_TYPE_MESSAGE\020\003\022\025\n\021" + "TARGET_TYPE_FIELD\020\004\022\025\n\021TARGET_TYPE_ONEOF" + "\020\005\022\024\n\020TARGET_TYPE_ENUM\020\006\022\032\n\026TARGET_TYPE_" + "ENUM_ENTRY\020\007\022\027\n\023TARGET_TYPE_SERVICE\020\010\022\026\n" + "\022TARGET_TYPE_METHOD\020\t*\t\010\350\007\020\200\200\200\200\002J\004\010\004\020\005J\004" + "\010\022\020\023\"\215\001\n\014OneofOptions\022-\n\010features\030\001 \001(\0132" + "\033.google.protobuf.FeatureSet\022C\n\024uninterp" + "reted_option\030\347\007 \003(\0132$.google.protobuf.Un" + "interpretedOption*\t\010\350\007\020\200\200\200\200\002\"\366\001\n\013EnumOpt" + "ions\022\023\n\013allow_alias\030\002 \001(\010\022\031\n\ndeprecated\030" + "\003 \001(\010:\005false\0222\n&deprecated_legacy_json_f" + "ield_conflicts\030\006 \001(\010B\002\030\001\022-\n\010features\030\007 \001" + "(\0132\033.google.protobuf.FeatureSet\022C\n\024unint" + "erpreted_option\030\347\007 \003(\0132$.google.protobuf" + ".UninterpretedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\005\020\006\"\311\001" + "\n\020EnumValueOptions\022\031\n\ndeprecated\030\001 \001(\010:\005" + "false\022-\n\010features\030\002 \001(\0132\033.google.protobu" + "f.FeatureSet\022\033\n\014debug_redact\030\003 \001(\010:\005fals" + "e\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.googl" "e.protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200" - "\002J\004\010\004\020\005J\004\010\005\020\006J\004\010\006\020\007J\004\010\010\020\tJ\004\010\t\020\n\"\215\t\n\014Fiel" - "dOptions\022:\n\005ctype\030\001 \001(\0162#.google.protobu" - "f.FieldOptions.CType:\006STRING\022\016\n\006packed\030\002" - " \001(\010\022\?\n\006jstype\030\006 \001(\0162$.google.protobuf.F" - "ieldOptions.JSType:\tJS_NORMAL\022\023\n\004lazy\030\005 " - "\001(\010:\005false\022\036\n\017unverified_lazy\030\017 \001(\010:\005fal" - "se\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\023\n\004weak\030\n " - "\001(\010:\005false\022\033\n\014debug_redact\030\020 \001(\010:\005false\022" - "@\n\tretention\030\021 \001(\0162-.google.protobuf.Fie" - "ldOptions.OptionRetention\022\?\n\007targets\030\023 \003" - "(\0162..google.protobuf.FieldOptions.Option" - "TargetType\022F\n\020edition_defaults\030\024 \003(\0132,.g" - "oogle.protobuf.FieldOptions.EditionDefau" - "lt\022-\n\010features\030\025 \001(\0132\033.google.protobuf.F" - "eatureSet\022C\n\024uninterpreted_option\030\347\007 \003(\013" - "2$.google.protobuf.UninterpretedOption\032J" - "\n\016EditionDefault\022)\n\007edition\030\003 \001(\0162\030.goog" - "le.protobuf.Edition\022\r\n\005value\030\002 \001(\t\"/\n\005CT" - "ype\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_PIEC" - "E\020\002\"5\n\006JSType\022\r\n\tJS_NORMAL\020\000\022\r\n\tJS_STRIN" - "G\020\001\022\r\n\tJS_NUMBER\020\002\"U\n\017OptionRetention\022\025\n" - "\021RETENTION_UNKNOWN\020\000\022\025\n\021RETENTION_RUNTIM" - "E\020\001\022\024\n\020RETENTION_SOURCE\020\002\"\214\002\n\020OptionTarg" - "etType\022\027\n\023TARGET_TYPE_UNKNOWN\020\000\022\024\n\020TARGE" - "T_TYPE_FILE\020\001\022\037\n\033TARGET_TYPE_EXTENSION_R" - "ANGE\020\002\022\027\n\023TARGET_TYPE_MESSAGE\020\003\022\025\n\021TARGE" - "T_TYPE_FIELD\020\004\022\025\n\021TARGET_TYPE_ONEOF\020\005\022\024\n" - "\020TARGET_TYPE_ENUM\020\006\022\032\n\026TARGET_TYPE_ENUM_" - "ENTRY\020\007\022\027\n\023TARGET_TYPE_SERVICE\020\010\022\026\n\022TARG" - "ET_TYPE_METHOD\020\t*\t\010\350\007\020\200\200\200\200\002J\004\010\004\020\005J\004\010\022\020\023\"" - "\215\001\n\014OneofOptions\022-\n\010features\030\001 \001(\0132\033.goo" - "gle.protobuf.FeatureSet\022C\n\024uninterpreted" - "_option\030\347\007 \003(\0132$.google.protobuf.Uninter" - "pretedOption*\t\010\350\007\020\200\200\200\200\002\"\366\001\n\013EnumOptions\022" - "\023\n\013allow_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010" - ":\005false\0222\n&deprecated_legacy_json_field_" - "conflicts\030\006 \001(\010B\002\030\001\022-\n\010features\030\007 \001(\0132\033." - "google.protobuf.FeatureSet\022C\n\024uninterpre" - "ted_option\030\347\007 \003(\0132$.google.protobuf.Unin" - "terpretedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\005\020\006\"\311\001\n\020Enu" - "mValueOptions\022\031\n\ndeprecated\030\001 \001(\010:\005false" - "\022-\n\010features\030\002 \001(\0132\033.google.protobuf.Fea" - "tureSet\022\033\n\014debug_redact\030\003 \001(\010:\005false\022C\n\024" - "uninterpreted_option\030\347\007 \003(\0132$.google.pro" - "tobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\252\001\n" - "\016ServiceOptions\022-\n\010features\030\" \001(\0132\033.goog" - "le.protobuf.FeatureSet\022\031\n\ndeprecated\030! \001" - "(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003(\013" - "2$.google.protobuf.UninterpretedOption*\t" - "\010\350\007\020\200\200\200\200\002\"\334\002\n\rMethodOptions\022\031\n\ndeprecate" - "d\030! \001(\010:\005false\022_\n\021idempotency_level\030\" \001(" - "\0162/.google.protobuf.MethodOptions.Idempo" - "tencyLevel:\023IDEMPOTENCY_UNKNOWN\022-\n\010featu" - "res\030# \001(\0132\033.google.protobuf.FeatureSet\022C" - "\n\024uninterpreted_option\030\347\007 \003(\0132$.google.p" - "rotobuf.UninterpretedOption\"P\n\020Idempoten" - "cyLevel\022\027\n\023IDEMPOTENCY_UNKNOWN\020\000\022\023\n\017NO_S" - "IDE_EFFECTS\020\001\022\016\n\nIDEMPOTENT\020\002*\t\010\350\007\020\200\200\200\200\002" - "\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003(\0132-" - ".google.protobuf.UninterpretedOption.Nam" - "ePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022posit" - "ive_int_value\030\004 \001(\004\022\032\n\022negative_int_valu" - "e\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014string_" - "value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323\n\010" - "NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_extens" - "ion\030\002 \002(\010\"\235\t\n\nFeatureSet\022|\n\016field_presen" - "ce\030\001 \001(\0162).google.protobuf.FeatureSet.Fi" - "eldPresenceB9\210\001\001\230\001\004\230\001\001\242\001\r\022\010EXPLICIT\030\346\007\242\001" - "\r\022\010IMPLICIT\030\347\007\242\001\r\022\010EXPLICIT\030\350\007\022\\\n\tenum_t" - "ype\030\002 \001(\0162$.google.protobuf.FeatureSet.E" - "numTypeB#\210\001\001\230\001\006\230\001\001\242\001\013\022\006CLOSED\030\346\007\242\001\t\022\004OPE" - "N\030\347\007\022{\n\027repeated_field_encoding\030\003 \001(\01621." - "google.protobuf.FeatureSet.RepeatedField" - "EncodingB\'\210\001\001\230\001\004\230\001\001\242\001\r\022\010EXPANDED\030\346\007\242\001\013\022\006" - "PACKED\030\347\007\022h\n\017utf8_validation\030\004 \001(\0162*.goo" - "gle.protobuf.FeatureSet.Utf8ValidationB#" - "\210\001\001\230\001\004\230\001\001\242\001\t\022\004NONE\030\346\007\242\001\013\022\006VERIFY\030\347\007\022g\n\020m" - "essage_encoding\030\005 \001(\0162+.google.protobuf." - "FeatureSet.MessageEncodingB \210\001\001\230\001\004\230\001\001\242\001\024" - "\022\017LENGTH_PREFIXED\030\346\007\022p\n\013json_format\030\006 \001(" - "\0162&.google.protobuf.FeatureSet.JsonForma" - "tB3\210\001\001\230\001\003\230\001\006\230\001\001\242\001\027\022\022LEGACY_BEST_EFFORT\030\346" - "\007\242\001\n\022\005ALLOW\030\347\007\"\\\n\rFieldPresence\022\032\n\026FIELD" - "_PRESENCE_UNKNOWN\020\000\022\014\n\010EXPLICIT\020\001\022\014\n\010IMP" - "LICIT\020\002\022\023\n\017LEGACY_REQUIRED\020\003\"7\n\010EnumType" - "\022\025\n\021ENUM_TYPE_UNKNOWN\020\000\022\010\n\004OPEN\020\001\022\n\n\006CLO" - "SED\020\002\"V\n\025RepeatedFieldEncoding\022#\n\037REPEAT" - "ED_FIELD_ENCODING_UNKNOWN\020\000\022\n\n\006PACKED\020\001\022" - "\014\n\010EXPANDED\020\002\"C\n\016Utf8Validation\022\033\n\027UTF8_" - "VALIDATION_UNKNOWN\020\000\022\010\n\004NONE\020\001\022\n\n\006VERIFY" - "\020\002\"S\n\017MessageEncoding\022\034\n\030MESSAGE_ENCODIN" - "G_UNKNOWN\020\000\022\023\n\017LENGTH_PREFIXED\020\001\022\r\n\tDELI" - "MITED\020\002\"H\n\nJsonFormat\022\027\n\023JSON_FORMAT_UNK" - "NOWN\020\000\022\t\n\005ALLOW\020\001\022\026\n\022LEGACY_BEST_EFFORT\020" - "\002*\006\010\350\007\020\351\007*\006\010\351\007\020\352\007*\006\010\213N\020\220NJ\006\010\347\007\020\350\007\"\300\002\n\022Fe" - "atureSetDefaults\022N\n\010defaults\030\001 \003(\0132<.goo" - "gle.protobuf.FeatureSetDefaults.FeatureS" - "etEditionDefault\0221\n\017minimum_edition\030\004 \001(" - "\0162\030.google.protobuf.Edition\0221\n\017maximum_e" - "dition\030\005 \001(\0162\030.google.protobuf.Edition\032t" - "\n\030FeatureSetEditionDefault\022)\n\007edition\030\003 " - "\001(\0162\030.google.protobuf.Edition\022-\n\010feature" - "s\030\002 \001(\0132\033.google.protobuf.FeatureSet\"\325\001\n" - "\016SourceCodeInfo\022:\n\010location\030\001 \003(\0132(.goog" - "le.protobuf.SourceCodeInfo.Location\032\206\001\n\010" - "Location\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005" - "B\002\020\001\022\030\n\020leading_comments\030\003 \001(\t\022\031\n\021traili" - "ng_comments\030\004 \001(\t\022!\n\031leading_detached_co" - "mments\030\006 \003(\t\"\234\002\n\021GeneratedCodeInfo\022A\n\nan" - "notation\030\001 \003(\0132-.google.protobuf.Generat" - "edCodeInfo.Annotation\032\303\001\n\nAnnotation\022\020\n\004" - "path\030\001 \003(\005B\002\020\001\022\023\n\013source_file\030\002 \001(\t\022\r\n\005b" - "egin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005\022H\n\010semantic\030\005 \001(" - "\01626.google.protobuf.GeneratedCodeInfo.An" - "notation.Semantic\"(\n\010Semantic\022\010\n\004NONE\020\000\022" - "\007\n\003SET\020\001\022\t\n\005ALIAS\020\002*\352\001\n\007Edition\022\023\n\017EDITI" - "ON_UNKNOWN\020\000\022\023\n\016EDITION_PROTO2\020\346\007\022\023\n\016EDI" - "TION_PROTO3\020\347\007\022\021\n\014EDITION_2023\020\350\007\022\027\n\023EDI" - "TION_1_TEST_ONLY\020\001\022\027\n\023EDITION_2_TEST_ONL" - "Y\020\002\022\035\n\027EDITION_99997_TEST_ONLY\020\235\215\006\022\035\n\027ED" - "ITION_99998_TEST_ONLY\020\236\215\006\022\035\n\027EDITION_999" - "99_TEST_ONLY\020\237\215\006B~\n\023com.google.protobufB" - "\020DescriptorProtosH\001Z-google.golang.org/p" - "rotobuf/types/descriptorpb\370\001\001\242\002\003GPB\252\002\032Go" - "ogle.Protobuf.Reflection" + "\002\"\252\001\n\016ServiceOptions\022-\n\010features\030\" \001(\0132\033" + ".google.protobuf.FeatureSet\022\031\n\ndeprecate" + "d\030! \001(\010:\005false\022C\n\024uninterpreted_option\030\347" + "\007 \003(\0132$.google.protobuf.UninterpretedOpt" + "ion*\t\010\350\007\020\200\200\200\200\002\"\334\002\n\rMethodOptions\022\031\n\ndepr" + "ecated\030! \001(\010:\005false\022_\n\021idempotency_level" + "\030\" \001(\0162/.google.protobuf.MethodOptions.I" + "dempotencyLevel:\023IDEMPOTENCY_UNKNOWN\022-\n\010" + "features\030# \001(\0132\033.google.protobuf.Feature" + "Set\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goo" + "gle.protobuf.UninterpretedOption\"P\n\020Idem" + "potencyLevel\022\027\n\023IDEMPOTENCY_UNKNOWN\020\000\022\023\n" + "\017NO_SIDE_EFFECTS\020\001\022\016\n\nIDEMPOTENT\020\002*\t\010\350\007\020" + "\200\200\200\200\002\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 " + "\003(\0132-.google.protobuf.UninterpretedOptio" + "n.NamePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022" + "positive_int_value\030\004 \001(\004\022\032\n\022negative_int" + "_value\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014st" + "ring_value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(" + "\t\0323\n\010NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_e" + "xtension\030\002 \002(\010\"\235\t\n\nFeatureSet\022|\n\016field_p" + "resence\030\001 \001(\0162).google.protobuf.FeatureS" + "et.FieldPresenceB9\210\001\001\230\001\004\230\001\001\242\001\r\022\010EXPLICIT" + "\030\346\007\242\001\r\022\010IMPLICIT\030\347\007\242\001\r\022\010EXPLICIT\030\350\007\022\\\n\te" + "num_type\030\002 \001(\0162$.google.protobuf.Feature" + "Set.EnumTypeB#\210\001\001\230\001\006\230\001\001\242\001\013\022\006CLOSED\030\346\007\242\001\t" + "\022\004OPEN\030\347\007\022{\n\027repeated_field_encoding\030\003 \001" + "(\01621.google.protobuf.FeatureSet.Repeated" + "FieldEncodingB\'\210\001\001\230\001\004\230\001\001\242\001\r\022\010EXPANDED\030\346\007" + "\242\001\013\022\006PACKED\030\347\007\022h\n\017utf8_validation\030\004 \001(\0162" + "*.google.protobuf.FeatureSet.Utf8Validat" + "ionB#\210\001\001\230\001\004\230\001\001\242\001\t\022\004NONE\030\346\007\242\001\013\022\006VERIFY\030\347\007" + "\022g\n\020message_encoding\030\005 \001(\0162+.google.prot" + "obuf.FeatureSet.MessageEncodingB \210\001\001\230\001\004\230" + "\001\001\242\001\024\022\017LENGTH_PREFIXED\030\346\007\022p\n\013json_format" + "\030\006 \001(\0162&.google.protobuf.FeatureSet.Json" + "FormatB3\210\001\001\230\001\003\230\001\006\230\001\001\242\001\027\022\022LEGACY_BEST_EFF" + "ORT\030\346\007\242\001\n\022\005ALLOW\030\347\007\"\\\n\rFieldPresence\022\032\n\026" + "FIELD_PRESENCE_UNKNOWN\020\000\022\014\n\010EXPLICIT\020\001\022\014" + "\n\010IMPLICIT\020\002\022\023\n\017LEGACY_REQUIRED\020\003\"7\n\010Enu" + "mType\022\025\n\021ENUM_TYPE_UNKNOWN\020\000\022\010\n\004OPEN\020\001\022\n" + "\n\006CLOSED\020\002\"V\n\025RepeatedFieldEncoding\022#\n\037R" + "EPEATED_FIELD_ENCODING_UNKNOWN\020\000\022\n\n\006PACK" + "ED\020\001\022\014\n\010EXPANDED\020\002\"C\n\016Utf8Validation\022\033\n\027" + "UTF8_VALIDATION_UNKNOWN\020\000\022\n\n\006VERIFY\020\002\022\010\n" + "\004NONE\020\003\"S\n\017MessageEncoding\022\034\n\030MESSAGE_EN" + "CODING_UNKNOWN\020\000\022\023\n\017LENGTH_PREFIXED\020\001\022\r\n" + "\tDELIMITED\020\002\"H\n\nJsonFormat\022\027\n\023JSON_FORMA" + "T_UNKNOWN\020\000\022\t\n\005ALLOW\020\001\022\026\n\022LEGACY_BEST_EF" + "FORT\020\002*\006\010\350\007\020\351\007*\006\010\351\007\020\352\007*\006\010\213N\020\220NJ\006\010\347\007\020\350\007\"\300" + "\002\n\022FeatureSetDefaults\022N\n\010defaults\030\001 \003(\0132" + "<.google.protobuf.FeatureSetDefaults.Fea" + "tureSetEditionDefault\0221\n\017minimum_edition" + "\030\004 \001(\0162\030.google.protobuf.Edition\0221\n\017maxi" + "mum_edition\030\005 \001(\0162\030.google.protobuf.Edit" + "ion\032t\n\030FeatureSetEditionDefault\022)\n\007editi" + "on\030\003 \001(\0162\030.google.protobuf.Edition\022-\n\010fe" + "atures\030\002 \001(\0132\033.google.protobuf.FeatureSe" + "t\"\325\001\n\016SourceCodeInfo\022:\n\010location\030\001 \003(\0132(" + ".google.protobuf.SourceCodeInfo.Location" + "\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004span\030" + "\002 \003(\005B\002\020\001\022\030\n\020leading_comments\030\003 \001(\t\022\031\n\021t" + "railing_comments\030\004 \001(\t\022!\n\031leading_detach" + "ed_comments\030\006 \003(\t\"\234\002\n\021GeneratedCodeInfo\022" + "A\n\nannotation\030\001 \003(\0132-.google.protobuf.Ge" + "neratedCodeInfo.Annotation\032\303\001\n\nAnnotatio" + "n\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source_file\030\002 \001(\t" + "\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005\022H\n\010semantic" + "\030\005 \001(\01626.google.protobuf.GeneratedCodeIn" + "fo.Annotation.Semantic\"(\n\010Semantic\022\010\n\004NO" + "NE\020\000\022\007\n\003SET\020\001\022\t\n\005ALIAS\020\002*\377\001\n\007Edition\022\023\n\017" + "EDITION_UNKNOWN\020\000\022\023\n\016EDITION_PROTO2\020\346\007\022\023" + "\n\016EDITION_PROTO3\020\347\007\022\021\n\014EDITION_2023\020\350\007\022\027" + "\n\023EDITION_1_TEST_ONLY\020\001\022\027\n\023EDITION_2_TES" + "T_ONLY\020\002\022\035\n\027EDITION_99997_TEST_ONLY\020\235\215\006\022" + "\035\n\027EDITION_99998_TEST_ONLY\020\236\215\006\022\035\n\027EDITIO" + "N_99999_TEST_ONLY\020\237\215\006\022\023\n\013EDITION_MAX\020\377\377\377" + "\377\007B~\n\023com.google.protobufB\020DescriptorPro" + "tosH\001Z-google.golang.org/protobuf/types/" + "descriptorpb\370\001\001\242\002\003GPB\252\002\032Google.Protobuf." + "Reflection" }; static ::absl::once_flag descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once; const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fdescriptor_2eproto = { false, false, - 9544, + 9570, descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto, "google/protobuf/descriptor.proto", &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, @@ -2260,16 +2262,16 @@ const ::google::protobuf::EnumDescriptor* FeatureSet_Utf8Validation_descriptor() return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[12]; } PROTOBUF_CONSTINIT const uint32_t FeatureSet_Utf8Validation_internal_data_[] = { - 196608u, 0u, }; + 65536u, 32u, 6u, }; bool FeatureSet_Utf8Validation_IsValid(int value) { - return 0 <= value && value <= 2; + return 0 <= value && value <= 3 && ((13u >> value) & 1) != 0; } #if (__cplusplus < 201703) && \ (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)) constexpr FeatureSet_Utf8Validation FeatureSet::UTF8_VALIDATION_UNKNOWN; -constexpr FeatureSet_Utf8Validation FeatureSet::NONE; constexpr FeatureSet_Utf8Validation FeatureSet::VERIFY; +constexpr FeatureSet_Utf8Validation FeatureSet::NONE; constexpr FeatureSet_Utf8Validation FeatureSet::Utf8Validation_MIN; constexpr FeatureSet_Utf8Validation FeatureSet::Utf8Validation_MAX; constexpr int FeatureSet::Utf8Validation_ARRAYSIZE; @@ -2344,7 +2346,7 @@ const ::google::protobuf::EnumDescriptor* Edition_descriptor() { return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[16]; } PROTOBUF_CONSTINIT const uint32_t Edition_internal_data_[] = { - 196608u, 393216u, 99997u, 999u, 99999u, 998u, 1000u, 99998u, }; + 196608u, 458752u, 99997u, 999u, 99999u, 998u, 1000u, 99998u, 2147483647u, }; bool Edition_IsValid(int value) { return ::_pbi::ValidateEnum(value, Edition_internal_data_); } @@ -2399,12 +2401,13 @@ inline void FileDescriptorSet::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* FileDescriptorSet::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { FileDescriptorSet::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(FileDescriptorSet, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void FileDescriptorSet::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorSet) @@ -2437,6 +2440,9 @@ constexpr ::_pbi::TcParseTable<0, 1, 1, 0, 2> FileDescriptorSet::_table_ = { offsetof(decltype(_table_), aux_entries), &_FileDescriptorSet_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::FileDescriptorSet>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // repeated .google.protobuf.FileDescriptorProto file = 1; {::_pbi::TcParser::FastMtR1, @@ -2495,7 +2501,7 @@ constexpr ::_pbi::TcParseTable<0, 1, 1, 0, 2> FileDescriptorSet::_table_ = { } -void FileDescriptorSet::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void FileDescriptorSet::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorSet) @@ -2521,9 +2527,6 @@ PROTOBUF_NOINLINE bool FileDescriptorSet::IsInitialized() const { return true; } -::_pbi::CachedSize* FileDescriptorSet::AccessCachedSize() const { - return &_impl_._cached_size_; -} void FileDescriptorSet::InternalSwap(FileDescriptorSet* PROTOBUF_RESTRICT other) { using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); @@ -2531,9 +2534,9 @@ void FileDescriptorSet::InternalSwap(FileDescriptorSet* PROTOBUF_RESTRICT other) } ::google::protobuf::Metadata FileDescriptorSet::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[0]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[0]); } // =================================================================== @@ -2542,34 +2545,8 @@ class FileDescriptorProto::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_._has_bits_); - static void set_has_name(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_package(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static const ::google::protobuf::FileOptions& options(const FileDescriptorProto* msg); - static void set_has_options(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static const ::google::protobuf::SourceCodeInfo& source_code_info(const FileDescriptorProto* msg); - static void set_has_source_code_info(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_syntax(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_edition(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } }; -const ::google::protobuf::FileOptions& FileDescriptorProto::_Internal::options(const FileDescriptorProto* msg) { - return *msg->_impl_.options_; -} -const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::_Internal::source_code_info(const FileDescriptorProto* msg) { - return *msg->_impl_.source_code_info_; -} FileDescriptorProto::FileDescriptorProto(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -2601,12 +2578,12 @@ FileDescriptorProto::FileDescriptorProto( from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.options_ = (cached_has_bits & 0x00000008u) - ? CreateMaybeMessage<::google::protobuf::FileOptions>(arena, *from._impl_.options_) - : nullptr; - _impl_.source_code_info_ = (cached_has_bits & 0x00000010u) - ? CreateMaybeMessage<::google::protobuf::SourceCodeInfo>(arena, *from._impl_.source_code_info_) - : nullptr; + _impl_.options_ = (cached_has_bits & 0x00000008u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::FileOptions>( + arena, *from._impl_.options_) + : nullptr; + _impl_.source_code_info_ = (cached_has_bits & 0x00000010u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::SourceCodeInfo>( + arena, *from._impl_.source_code_info_) + : nullptr; _impl_.edition_ = from._impl_.edition_; // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorProto) @@ -2653,12 +2630,13 @@ inline void FileDescriptorProto::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* FileDescriptorProto::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { FileDescriptorProto::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void FileDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorProto) @@ -2719,6 +2697,9 @@ constexpr ::_pbi::TcParseTable<4, 13, 7, 79, 2> FileDescriptorProto::_table_ = { offsetof(decltype(_table_), aux_entries), &_FileDescriptorProto_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::FileDescriptorProto>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional string name = 1; @@ -2889,15 +2870,13 @@ constexpr ::_pbi::TcParseTable<4, 13, 7, 79, 2> FileDescriptorProto::_table_ = { // optional .google.protobuf.FileOptions options = 8; if (cached_has_bits & 0x00000008u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 8, _Internal::options(this), - _Internal::options(this).GetCachedSize(), target, stream); + 8, *_impl_.options_, _impl_.options_->GetCachedSize(), target, stream); } // optional .google.protobuf.SourceCodeInfo source_code_info = 9; if (cached_has_bits & 0x00000010u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 9, _Internal::source_code_info(this), - _Internal::source_code_info(this).GetCachedSize(), target, stream); + 9, *_impl_.source_code_info_, _impl_.source_code_info_->GetCachedSize(), target, stream); } // repeated int32 public_dependency = 10; @@ -3039,9 +3018,10 @@ constexpr ::_pbi::TcParseTable<4, 13, 7, 79, 2> FileDescriptorProto::_table_ = { } -void FileDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void FileDescriptorProto::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -3070,18 +3050,28 @@ void FileDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const : _this->_internal_set_syntax(from._internal_syntax()); } if (cached_has_bits & 0x00000008u) { - _this->_internal_mutable_options()->::google::protobuf::FileOptions::MergeFrom( - from._internal_options()); + ABSL_DCHECK(from._impl_.options_ != nullptr); + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::FileOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } if (cached_has_bits & 0x00000010u) { - _this->_internal_mutable_source_code_info()->::google::protobuf::SourceCodeInfo::MergeFrom( - from._internal_source_code_info()); + ABSL_DCHECK(from._impl_.source_code_info_ != nullptr); + if (_this->_impl_.source_code_info_ == nullptr) { + _this->_impl_.source_code_info_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::SourceCodeInfo>(arena, *from._impl_.source_code_info_); + } else { + _this->_impl_.source_code_info_->MergeFrom(*from._impl_.source_code_info_); + } } if (cached_has_bits & 0x00000020u) { _this->_impl_.edition_ = from._impl_.edition_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -3107,9 +3097,6 @@ PROTOBUF_NOINLINE bool FileDescriptorProto::IsInitialized() const { return true; } -::_pbi::CachedSize* FileDescriptorProto::AccessCachedSize() const { - return &_impl_._cached_size_; -} void FileDescriptorProto::InternalSwap(FileDescriptorProto* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -3135,9 +3122,9 @@ void FileDescriptorProto::InternalSwap(FileDescriptorProto* PROTOBUF_RESTRICT ot } ::google::protobuf::Metadata FileDescriptorProto::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[1]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[1]); } // =================================================================== @@ -3146,21 +3133,8 @@ class DescriptorProto_ExtensionRange::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_._has_bits_); - static void set_has_start(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_end(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static const ::google::protobuf::ExtensionRangeOptions& options(const DescriptorProto_ExtensionRange* msg); - static void set_has_options(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } }; -const ::google::protobuf::ExtensionRangeOptions& DescriptorProto_ExtensionRange::_Internal::options(const DescriptorProto_ExtensionRange* msg) { - return *msg->_impl_.options_; -} DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -3182,9 +3156,9 @@ DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange( from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.options_ = (cached_has_bits & 0x00000001u) - ? CreateMaybeMessage<::google::protobuf::ExtensionRangeOptions>(arena, *from._impl_.options_) - : nullptr; + _impl_.options_ = (cached_has_bits & 0x00000001u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::ExtensionRangeOptions>( + arena, *from._impl_.options_) + : nullptr; ::memcpy(reinterpret_cast(&_impl_) + offsetof(Impl_, start_), reinterpret_cast(&from._impl_) + @@ -3223,12 +3197,13 @@ inline void DescriptorProto_ExtensionRange::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* DescriptorProto_ExtensionRange::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { DescriptorProto_ExtensionRange::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void DescriptorProto_ExtensionRange::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ExtensionRange) @@ -3271,6 +3246,9 @@ constexpr ::_pbi::TcParseTable<2, 3, 1, 0, 2> DescriptorProto_ExtensionRange::_t offsetof(decltype(_table_), aux_entries), &_DescriptorProto_ExtensionRange_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::DescriptorProto_ExtensionRange>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional int32 start = 1; @@ -3325,8 +3303,7 @@ constexpr ::_pbi::TcParseTable<2, 3, 1, 0, 2> DescriptorProto_ExtensionRange::_t // optional .google.protobuf.ExtensionRangeOptions options = 3; if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 3, _Internal::options(this), - _Internal::options(this).GetCachedSize(), target, stream); + 3, *_impl_.options_, _impl_.options_->GetCachedSize(), target, stream); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { @@ -3371,9 +3348,10 @@ constexpr ::_pbi::TcParseTable<2, 3, 1, 0, 2> DescriptorProto_ExtensionRange::_t } -void DescriptorProto_ExtensionRange::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void DescriptorProto_ExtensionRange::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -3382,8 +3360,13 @@ void DescriptorProto_ExtensionRange::MergeImpl(::google::protobuf::Message& to_m cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000007u) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_options()->::google::protobuf::ExtensionRangeOptions::MergeFrom( - from._internal_options()); + ABSL_DCHECK(from._impl_.options_ != nullptr); + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::ExtensionRangeOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.start_ = from._impl_.start_; @@ -3391,8 +3374,8 @@ void DescriptorProto_ExtensionRange::MergeImpl(::google::protobuf::Message& to_m if (cached_has_bits & 0x00000004u) { _this->_impl_.end_ = from._impl_.end_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -3410,9 +3393,6 @@ PROTOBUF_NOINLINE bool DescriptorProto_ExtensionRange::IsInitialized() const { return true; } -::_pbi::CachedSize* DescriptorProto_ExtensionRange::AccessCachedSize() const { - return &_impl_._cached_size_; -} void DescriptorProto_ExtensionRange::InternalSwap(DescriptorProto_ExtensionRange* PROTOBUF_RESTRICT other) { using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); @@ -3426,9 +3406,9 @@ void DescriptorProto_ExtensionRange::InternalSwap(DescriptorProto_ExtensionRange } ::google::protobuf::Metadata DescriptorProto_ExtensionRange::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[2]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[2]); } // =================================================================== @@ -3437,12 +3417,6 @@ class DescriptorProto_ReservedRange::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, _impl_._has_bits_); - static void set_has_start(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_end(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } }; DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(::google::protobuf::Arena* arena) @@ -3482,12 +3456,13 @@ inline void DescriptorProto_ReservedRange::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* DescriptorProto_ReservedRange::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { DescriptorProto_ReservedRange::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void DescriptorProto_ReservedRange::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ReservedRange) @@ -3526,6 +3501,9 @@ constexpr ::_pbi::TcParseTable<1, 2, 0, 0, 2> DescriptorProto_ReservedRange::_ta offsetof(decltype(_table_), field_names), // no aux_entries &_DescriptorProto_ReservedRange_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::DescriptorProto_ReservedRange>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // optional int32 end = 2; {::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(DescriptorProto_ReservedRange, _impl_.end_), 1>(), @@ -3606,7 +3584,7 @@ constexpr ::_pbi::TcParseTable<1, 2, 0, 0, 2> DescriptorProto_ReservedRange::_ta } -void DescriptorProto_ReservedRange::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void DescriptorProto_ReservedRange::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ReservedRange) @@ -3622,8 +3600,8 @@ void DescriptorProto_ReservedRange::MergeImpl(::google::protobuf::Message& to_ms if (cached_has_bits & 0x00000002u) { _this->_impl_.end_ = from._impl_.end_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -3638,9 +3616,6 @@ PROTOBUF_NOINLINE bool DescriptorProto_ReservedRange::IsInitialized() const { return true; } -::_pbi::CachedSize* DescriptorProto_ReservedRange::AccessCachedSize() const { - return &_impl_._cached_size_; -} void DescriptorProto_ReservedRange::InternalSwap(DescriptorProto_ReservedRange* PROTOBUF_RESTRICT other) { using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); @@ -3654,9 +3629,9 @@ void DescriptorProto_ReservedRange::InternalSwap(DescriptorProto_ReservedRange* } ::google::protobuf::Metadata DescriptorProto_ReservedRange::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[3]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[3]); } // =================================================================== @@ -3665,18 +3640,8 @@ class DescriptorProto::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_._has_bits_); - static void set_has_name(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static const ::google::protobuf::MessageOptions& options(const DescriptorProto* msg); - static void set_has_options(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } }; -const ::google::protobuf::MessageOptions& DescriptorProto::_Internal::options(const DescriptorProto* msg) { - return *msg->_impl_.options_; -} DescriptorProto::DescriptorProto(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -3707,9 +3672,9 @@ DescriptorProto::DescriptorProto( from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.options_ = (cached_has_bits & 0x00000002u) - ? CreateMaybeMessage<::google::protobuf::MessageOptions>(arena, *from._impl_.options_) - : nullptr; + _impl_.options_ = (cached_has_bits & 0x00000002u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::MessageOptions>( + arena, *from._impl_.options_) + : nullptr; // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto) } @@ -3746,12 +3711,13 @@ inline void DescriptorProto::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* DescriptorProto::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { DescriptorProto::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void DescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto) @@ -3802,6 +3768,9 @@ constexpr ::_pbi::TcParseTable<4, 10, 8, 65, 2> DescriptorProto::_table_ = { offsetof(decltype(_table_), aux_entries), &_DescriptorProto_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::DescriptorProto>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional string name = 1; @@ -3948,8 +3917,7 @@ constexpr ::_pbi::TcParseTable<4, 10, 8, 65, 2> DescriptorProto::_table_ = { // optional .google.protobuf.MessageOptions options = 7; if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 7, _Internal::options(this), - _Internal::options(this).GetCachedSize(), target, stream); + 7, *_impl_.options_, _impl_.options_->GetCachedSize(), target, stream); } // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; @@ -4060,9 +4028,10 @@ constexpr ::_pbi::TcParseTable<4, 10, 8, 65, 2> DescriptorProto::_table_ = { } -void DescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void DescriptorProto::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -4089,10 +4058,16 @@ void DescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::goo _this->_internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _this->_internal_mutable_options()->::google::protobuf::MessageOptions::MergeFrom( - from._internal_options()); + ABSL_DCHECK(from._impl_.options_ != nullptr); + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::MessageOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -4122,9 +4097,6 @@ PROTOBUF_NOINLINE bool DescriptorProto::IsInitialized() const { return true; } -::_pbi::CachedSize* DescriptorProto::AccessCachedSize() const { - return &_impl_._cached_size_; -} void DescriptorProto::InternalSwap(DescriptorProto* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -4144,9 +4116,9 @@ void DescriptorProto::InternalSwap(DescriptorProto* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata DescriptorProto::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[4]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[4]); } // =================================================================== @@ -4155,21 +4127,6 @@ class ExtensionRangeOptions_Declaration::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions_Declaration, _impl_._has_bits_); - static void set_has_number(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_full_name(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_type(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_reserved(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_repeated(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } }; ExtensionRangeOptions_Declaration::ExtensionRangeOptions_Declaration(::google::protobuf::Arena* arena) @@ -4235,12 +4192,13 @@ inline void ExtensionRangeOptions_Declaration::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* ExtensionRangeOptions_Declaration::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { ExtensionRangeOptions_Declaration::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions_Declaration, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void ExtensionRangeOptions_Declaration::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.ExtensionRangeOptions.Declaration) @@ -4287,6 +4245,9 @@ constexpr ::_pbi::TcParseTable<3, 5, 0, 71, 2> ExtensionRangeOptions_Declaration offsetof(decltype(_table_), field_names), // no aux_entries &_ExtensionRangeOptions_Declaration_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::ExtensionRangeOptions_Declaration>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional int32 number = 1; @@ -4431,7 +4392,7 @@ constexpr ::_pbi::TcParseTable<3, 5, 0, 71, 2> ExtensionRangeOptions_Declaration } -void ExtensionRangeOptions_Declaration::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void ExtensionRangeOptions_Declaration::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ExtensionRangeOptions.Declaration) @@ -4456,8 +4417,8 @@ void ExtensionRangeOptions_Declaration::MergeImpl(::google::protobuf::Message& t if (cached_has_bits & 0x00000010u) { _this->_impl_.repeated_ = from._impl_.repeated_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -4472,9 +4433,6 @@ PROTOBUF_NOINLINE bool ExtensionRangeOptions_Declaration::IsInitialized() const return true; } -::_pbi::CachedSize* ExtensionRangeOptions_Declaration::AccessCachedSize() const { - return &_impl_._cached_size_; -} void ExtensionRangeOptions_Declaration::InternalSwap(ExtensionRangeOptions_Declaration* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -4492,9 +4450,9 @@ void ExtensionRangeOptions_Declaration::InternalSwap(ExtensionRangeOptions_Decla } ::google::protobuf::Metadata ExtensionRangeOptions_Declaration::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[5]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[5]); } // =================================================================== @@ -4503,18 +4461,8 @@ class ExtensionRangeOptions::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_._has_bits_); - static const ::google::protobuf::FeatureSet& features(const ExtensionRangeOptions* msg); - static void set_has_features(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_verification(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } }; -const ::google::protobuf::FeatureSet& ExtensionRangeOptions::_Internal::features(const ExtensionRangeOptions* msg) { - return *msg->_impl_.features_; -} ExtensionRangeOptions::ExtensionRangeOptions(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -4540,9 +4488,9 @@ ExtensionRangeOptions::ExtensionRangeOptions( new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); _impl_._extensions_.MergeFrom(this, from._impl_._extensions_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.features_ = (cached_has_bits & 0x00000001u) - ? CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_) - : nullptr; + _impl_.features_ = (cached_has_bits & 0x00000001u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>( + arena, *from._impl_.features_) + : nullptr; _impl_.verification_ = from._impl_.verification_; // @@protoc_insertion_point(copy_constructor:google.protobuf.ExtensionRangeOptions) @@ -4574,12 +4522,13 @@ inline void ExtensionRangeOptions::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* ExtensionRangeOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { ExtensionRangeOptions::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void ExtensionRangeOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.ExtensionRangeOptions) @@ -4623,13 +4572,16 @@ constexpr ::_pbi::TcParseTable<3, 4, 4, 0, 12> ExtensionRangeOptions::_table_ = offsetof(decltype(_table_), aux_entries), &_ExtensionRangeOptions_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::ExtensionRangeOptions>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, {::_pbi::TcParser::MiniParse, {}}, // repeated .google.protobuf.ExtensionRangeOptions.Declaration declaration = 2 [retention = RETENTION_SOURCE]; {::_pbi::TcParser::FastMtR1, {18, 63, 0, PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_.declaration_)}}, - // optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED]; + // optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED, retention = RETENTION_SOURCE]; {::_pbi::TcParser::FastEr0S1, {24, 1, 1, PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_.verification_)}}, {::_pbi::TcParser::MiniParse, {}}, @@ -4647,7 +4599,7 @@ constexpr ::_pbi::TcParseTable<3, 4, 4, 0, 12> ExtensionRangeOptions::_table_ = // repeated .google.protobuf.ExtensionRangeOptions.Declaration declaration = 2 [retention = RETENTION_SOURCE]; {PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_.declaration_), -1, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, - // optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED]; + // optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED, retention = RETENTION_SOURCE]; {PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_.verification_), _Internal::kHasBitsOffset + 1, 1, (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, // optional .google.protobuf.FeatureSet features = 50; @@ -4681,7 +4633,7 @@ constexpr ::_pbi::TcParseTable<3, 4, 4, 0, 12> ExtensionRangeOptions::_table_ = } cached_has_bits = _impl_._has_bits_[0]; - // optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED]; + // optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED, retention = RETENTION_SOURCE]; if (cached_has_bits & 0x00000002u) { target = stream->EnsureSpace(target); target = ::_pbi::WireFormatLite::WriteEnumToArray( @@ -4691,8 +4643,7 @@ constexpr ::_pbi::TcParseTable<3, 4, 4, 0, 12> ExtensionRangeOptions::_table_ = // optional .google.protobuf.FeatureSet features = 50; if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 50, _Internal::features(this), - _Internal::features(this).GetCachedSize(), target, stream); + 50, *_impl_.features_, _impl_.features_->GetCachedSize(), target, stream); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; @@ -4745,7 +4696,7 @@ constexpr ::_pbi::TcParseTable<3, 4, 4, 0, 12> ExtensionRangeOptions::_table_ = 2 + ::google::protobuf::internal::WireFormatLite::MessageSize(*_impl_.features_); } - // optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED]; + // optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED, retention = RETENTION_SOURCE]; if (cached_has_bits & 0x00000002u) { total_size += 1 + ::_pbi::WireFormatLite::EnumSize(this->_internal_verification()); @@ -4756,9 +4707,10 @@ constexpr ::_pbi::TcParseTable<3, 4, 4, 0, 12> ExtensionRangeOptions::_table_ = } -void ExtensionRangeOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void ExtensionRangeOptions::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ExtensionRangeOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -4771,14 +4723,19 @@ void ExtensionRangeOptions::MergeImpl(::google::protobuf::Message& to_msg, const cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000003u) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + ABSL_DCHECK(from._impl_.features_ != nullptr); + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.verification_ = from._impl_.verification_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_); _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -4802,9 +4759,6 @@ PROTOBUF_NOINLINE bool ExtensionRangeOptions::IsInitialized() const { return true; } -::_pbi::CachedSize* ExtensionRangeOptions::AccessCachedSize() const { - return &_impl_._cached_size_; -} void ExtensionRangeOptions::InternalSwap(ExtensionRangeOptions* PROTOBUF_RESTRICT other) { using std::swap; _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); @@ -4821,9 +4775,9 @@ void ExtensionRangeOptions::InternalSwap(ExtensionRangeOptions* PROTOBUF_RESTRIC } ::google::protobuf::Metadata ExtensionRangeOptions::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[6]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[6]); } // =================================================================== @@ -4832,45 +4786,8 @@ class FieldDescriptorProto::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_._has_bits_); - static void set_has_name(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_number(HasBits* has_bits) { - (*has_bits)[0] |= 64u; - } - static void set_has_label(HasBits* has_bits) { - (*has_bits)[0] |= 512u; - } - static void set_has_type(HasBits* has_bits) { - (*has_bits)[0] |= 1024u; - } - static void set_has_type_name(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_extendee(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_default_value(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_oneof_index(HasBits* has_bits) { - (*has_bits)[0] |= 128u; - } - static void set_has_json_name(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static const ::google::protobuf::FieldOptions& options(const FieldDescriptorProto* msg); - static void set_has_options(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static void set_has_proto3_optional(HasBits* has_bits) { - (*has_bits)[0] |= 256u; - } }; -const ::google::protobuf::FieldOptions& FieldDescriptorProto::_Internal::options(const FieldDescriptorProto* msg) { - return *msg->_impl_.options_; -} FieldDescriptorProto::FieldDescriptorProto(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -4897,9 +4814,9 @@ FieldDescriptorProto::FieldDescriptorProto( from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.options_ = (cached_has_bits & 0x00000020u) - ? CreateMaybeMessage<::google::protobuf::FieldOptions>(arena, *from._impl_.options_) - : nullptr; + _impl_.options_ = (cached_has_bits & 0x00000020u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::FieldOptions>( + arena, *from._impl_.options_) + : nullptr; ::memcpy(reinterpret_cast(&_impl_) + offsetof(Impl_, number_), reinterpret_cast(&from._impl_) + @@ -4950,12 +4867,13 @@ inline void FieldDescriptorProto::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* FieldDescriptorProto::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { FieldDescriptorProto::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void FieldDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FieldDescriptorProto) @@ -5020,6 +4938,9 @@ constexpr ::_pbi::TcParseTable<4, 11, 3, 96, 2> FieldDescriptorProto::_table_ = offsetof(decltype(_table_), aux_entries), &_FieldDescriptorProto_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::FieldDescriptorProto>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional string name = 1; @@ -5172,8 +5093,7 @@ constexpr ::_pbi::TcParseTable<4, 11, 3, 96, 2> FieldDescriptorProto::_table_ = // optional .google.protobuf.FieldOptions options = 8; if (cached_has_bits & 0x00000020u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 8, _Internal::options(this), - _Internal::options(this).GetCachedSize(), target, stream); + 8, *_impl_.options_, _impl_.options_->GetCachedSize(), target, stream); } // optional int32 oneof_index = 9; @@ -5289,9 +5209,10 @@ constexpr ::_pbi::TcParseTable<4, 11, 3, 96, 2> FieldDescriptorProto::_table_ = } -void FieldDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void FieldDescriptorProto::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -5315,8 +5236,13 @@ void FieldDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const _this->_internal_set_json_name(from._internal_json_name()); } if (cached_has_bits & 0x00000020u) { - _this->_internal_mutable_options()->::google::protobuf::FieldOptions::MergeFrom( - from._internal_options()); + ABSL_DCHECK(from._impl_.options_ != nullptr); + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::FieldOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } if (cached_has_bits & 0x00000040u) { _this->_impl_.number_ = from._impl_.number_; @@ -5324,7 +5250,6 @@ void FieldDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const if (cached_has_bits & 0x00000080u) { _this->_impl_.oneof_index_ = from._impl_.oneof_index_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } if (cached_has_bits & 0x00000700u) { if (cached_has_bits & 0x00000100u) { @@ -5336,8 +5261,8 @@ void FieldDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const if (cached_has_bits & 0x00000400u) { _this->_impl_.type_ = from._impl_.type_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -5355,9 +5280,6 @@ PROTOBUF_NOINLINE bool FieldDescriptorProto::IsInitialized() const { return true; } -::_pbi::CachedSize* FieldDescriptorProto::AccessCachedSize() const { - return &_impl_._cached_size_; -} void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -5378,9 +5300,9 @@ void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* PROTOBUF_RESTRICT } ::google::protobuf::Metadata FieldDescriptorProto::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[7]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[7]); } // =================================================================== @@ -5389,18 +5311,8 @@ class OneofDescriptorProto::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(OneofDescriptorProto, _impl_._has_bits_); - static void set_has_name(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static const ::google::protobuf::OneofOptions& options(const OneofDescriptorProto* msg); - static void set_has_options(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } }; -const ::google::protobuf::OneofOptions& OneofDescriptorProto::_Internal::options(const OneofDescriptorProto* msg) { - return *msg->_impl_.options_; -} OneofDescriptorProto::OneofDescriptorProto(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -5423,9 +5335,9 @@ OneofDescriptorProto::OneofDescriptorProto( from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.options_ = (cached_has_bits & 0x00000002u) - ? CreateMaybeMessage<::google::protobuf::OneofOptions>(arena, *from._impl_.options_) - : nullptr; + _impl_.options_ = (cached_has_bits & 0x00000002u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::OneofOptions>( + arena, *from._impl_.options_) + : nullptr; // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofDescriptorProto) } @@ -5454,12 +5366,13 @@ inline void OneofDescriptorProto::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* OneofDescriptorProto::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { OneofDescriptorProto::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(OneofDescriptorProto, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void OneofDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.OneofDescriptorProto) @@ -5502,6 +5415,9 @@ constexpr ::_pbi::TcParseTable<1, 2, 1, 49, 2> OneofDescriptorProto::_table_ = { offsetof(decltype(_table_), aux_entries), &_OneofDescriptorProto_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::OneofDescriptorProto>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // optional .google.protobuf.OneofOptions options = 2; {::_pbi::TcParser::FastMtS1, @@ -5546,8 +5462,7 @@ constexpr ::_pbi::TcParseTable<1, 2, 1, 49, 2> OneofDescriptorProto::_table_ = { // optional .google.protobuf.OneofOptions options = 2; if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 2, _Internal::options(this), - _Internal::options(this).GetCachedSize(), target, stream); + 2, *_impl_.options_, _impl_.options_->GetCachedSize(), target, stream); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { @@ -5586,9 +5501,10 @@ constexpr ::_pbi::TcParseTable<1, 2, 1, 49, 2> OneofDescriptorProto::_table_ = { } -void OneofDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void OneofDescriptorProto::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -5600,10 +5516,16 @@ void OneofDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const _this->_internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _this->_internal_mutable_options()->::google::protobuf::OneofOptions::MergeFrom( - from._internal_options()); + ABSL_DCHECK(from._impl_.options_ != nullptr); + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::OneofOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -5621,9 +5543,6 @@ PROTOBUF_NOINLINE bool OneofDescriptorProto::IsInitialized() const { return true; } -::_pbi::CachedSize* OneofDescriptorProto::AccessCachedSize() const { - return &_impl_._cached_size_; -} void OneofDescriptorProto::InternalSwap(OneofDescriptorProto* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -5635,9 +5554,9 @@ void OneofDescriptorProto::InternalSwap(OneofDescriptorProto* PROTOBUF_RESTRICT } ::google::protobuf::Metadata OneofDescriptorProto::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[8]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[8]); } // =================================================================== @@ -5646,12 +5565,6 @@ class EnumDescriptorProto_EnumReservedRange::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, _impl_._has_bits_); - static void set_has_start(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_end(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } }; EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(::google::protobuf::Arena* arena) @@ -5691,12 +5604,13 @@ inline void EnumDescriptorProto_EnumReservedRange::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* EnumDescriptorProto_EnumReservedRange::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { EnumDescriptorProto_EnumReservedRange::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void EnumDescriptorProto_EnumReservedRange::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto.EnumReservedRange) @@ -5735,6 +5649,9 @@ constexpr ::_pbi::TcParseTable<1, 2, 0, 0, 2> EnumDescriptorProto_EnumReservedRa offsetof(decltype(_table_), field_names), // no aux_entries &_EnumDescriptorProto_EnumReservedRange_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::EnumDescriptorProto_EnumReservedRange>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // optional int32 end = 2; {::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(EnumDescriptorProto_EnumReservedRange, _impl_.end_), 1>(), @@ -5815,7 +5732,7 @@ constexpr ::_pbi::TcParseTable<1, 2, 0, 0, 2> EnumDescriptorProto_EnumReservedRa } -void EnumDescriptorProto_EnumReservedRange::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void EnumDescriptorProto_EnumReservedRange::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto.EnumReservedRange) @@ -5831,8 +5748,8 @@ void EnumDescriptorProto_EnumReservedRange::MergeImpl(::google::protobuf::Messag if (cached_has_bits & 0x00000002u) { _this->_impl_.end_ = from._impl_.end_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -5847,9 +5764,6 @@ PROTOBUF_NOINLINE bool EnumDescriptorProto_EnumReservedRange::IsInitialized() co return true; } -::_pbi::CachedSize* EnumDescriptorProto_EnumReservedRange::AccessCachedSize() const { - return &_impl_._cached_size_; -} void EnumDescriptorProto_EnumReservedRange::InternalSwap(EnumDescriptorProto_EnumReservedRange* PROTOBUF_RESTRICT other) { using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); @@ -5863,9 +5777,9 @@ void EnumDescriptorProto_EnumReservedRange::InternalSwap(EnumDescriptorProto_Enu } ::google::protobuf::Metadata EnumDescriptorProto_EnumReservedRange::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[9]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[9]); } // =================================================================== @@ -5874,18 +5788,8 @@ class EnumDescriptorProto::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_._has_bits_); - static void set_has_name(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static const ::google::protobuf::EnumOptions& options(const EnumDescriptorProto* msg); - static void set_has_options(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } }; -const ::google::protobuf::EnumOptions& EnumDescriptorProto::_Internal::options(const EnumDescriptorProto* msg) { - return *msg->_impl_.options_; -} EnumDescriptorProto::EnumDescriptorProto(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -5911,9 +5815,9 @@ EnumDescriptorProto::EnumDescriptorProto( from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.options_ = (cached_has_bits & 0x00000002u) - ? CreateMaybeMessage<::google::protobuf::EnumOptions>(arena, *from._impl_.options_) - : nullptr; + _impl_.options_ = (cached_has_bits & 0x00000002u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::EnumOptions>( + arena, *from._impl_.options_) + : nullptr; // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumDescriptorProto) } @@ -5945,12 +5849,13 @@ inline void EnumDescriptorProto::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* EnumDescriptorProto::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { EnumDescriptorProto::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void EnumDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto) @@ -5996,6 +5901,9 @@ constexpr ::_pbi::TcParseTable<3, 5, 3, 61, 2> EnumDescriptorProto::_table_ = { offsetof(decltype(_table_), aux_entries), &_EnumDescriptorProto_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::EnumDescriptorProto>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional string name = 1; @@ -6072,8 +5980,7 @@ constexpr ::_pbi::TcParseTable<3, 5, 3, 61, 2> EnumDescriptorProto::_table_ = { // optional .google.protobuf.EnumOptions options = 3; if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 3, _Internal::options(this), - _Internal::options(this).GetCachedSize(), target, stream); + 3, *_impl_.options_, _impl_.options_->GetCachedSize(), target, stream); } // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; @@ -6146,9 +6053,10 @@ constexpr ::_pbi::TcParseTable<3, 5, 3, 61, 2> EnumDescriptorProto::_table_ = { } -void EnumDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void EnumDescriptorProto::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -6165,10 +6073,16 @@ void EnumDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const : _this->_internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _this->_internal_mutable_options()->::google::protobuf::EnumOptions::MergeFrom( - from._internal_options()); + ABSL_DCHECK(from._impl_.options_ != nullptr); + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::EnumOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -6188,9 +6102,6 @@ PROTOBUF_NOINLINE bool EnumDescriptorProto::IsInitialized() const { return true; } -::_pbi::CachedSize* EnumDescriptorProto::AccessCachedSize() const { - return &_impl_._cached_size_; -} void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -6205,9 +6116,9 @@ void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* PROTOBUF_RESTRICT ot } ::google::protobuf::Metadata EnumDescriptorProto::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[10]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[10]); } // =================================================================== @@ -6216,21 +6127,8 @@ class EnumValueDescriptorProto::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_._has_bits_); - static void set_has_name(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_number(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static const ::google::protobuf::EnumValueOptions& options(const EnumValueDescriptorProto* msg); - static void set_has_options(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } }; -const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::_Internal::options(const EnumValueDescriptorProto* msg) { - return *msg->_impl_.options_; -} EnumValueDescriptorProto::EnumValueDescriptorProto(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -6253,9 +6151,9 @@ EnumValueDescriptorProto::EnumValueDescriptorProto( from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.options_ = (cached_has_bits & 0x00000002u) - ? CreateMaybeMessage<::google::protobuf::EnumValueOptions>(arena, *from._impl_.options_) - : nullptr; + _impl_.options_ = (cached_has_bits & 0x00000002u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::EnumValueOptions>( + arena, *from._impl_.options_) + : nullptr; _impl_.number_ = from._impl_.number_; // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueDescriptorProto) @@ -6290,12 +6188,13 @@ inline void EnumValueDescriptorProto::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* EnumValueDescriptorProto::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { EnumValueDescriptorProto::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void EnumValueDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueDescriptorProto) @@ -6339,6 +6238,9 @@ constexpr ::_pbi::TcParseTable<2, 3, 1, 53, 2> EnumValueDescriptorProto::_table_ offsetof(decltype(_table_), aux_entries), &_EnumValueDescriptorProto_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::EnumValueDescriptorProto>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional string name = 1; @@ -6397,8 +6299,7 @@ constexpr ::_pbi::TcParseTable<2, 3, 1, 53, 2> EnumValueDescriptorProto::_table_ // optional .google.protobuf.EnumValueOptions options = 3; if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 3, _Internal::options(this), - _Internal::options(this).GetCachedSize(), target, stream); + 3, *_impl_.options_, _impl_.options_->GetCachedSize(), target, stream); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { @@ -6443,9 +6344,10 @@ constexpr ::_pbi::TcParseTable<2, 3, 1, 53, 2> EnumValueDescriptorProto::_table_ } -void EnumValueDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void EnumValueDescriptorProto::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -6457,14 +6359,19 @@ void EnumValueDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, co _this->_internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _this->_internal_mutable_options()->::google::protobuf::EnumValueOptions::MergeFrom( - from._internal_options()); + ABSL_DCHECK(from._impl_.options_ != nullptr); + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::EnumValueOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } if (cached_has_bits & 0x00000004u) { _this->_impl_.number_ = from._impl_.number_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -6482,9 +6389,6 @@ PROTOBUF_NOINLINE bool EnumValueDescriptorProto::IsInitialized() const { return true; } -::_pbi::CachedSize* EnumValueDescriptorProto::AccessCachedSize() const { - return &_impl_._cached_size_; -} void EnumValueDescriptorProto::InternalSwap(EnumValueDescriptorProto* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -6501,9 +6405,9 @@ void EnumValueDescriptorProto::InternalSwap(EnumValueDescriptorProto* PROTOBUF_R } ::google::protobuf::Metadata EnumValueDescriptorProto::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[11]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[11]); } // =================================================================== @@ -6512,18 +6416,8 @@ class ServiceDescriptorProto::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(ServiceDescriptorProto, _impl_._has_bits_); - static void set_has_name(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static const ::google::protobuf::ServiceOptions& options(const ServiceDescriptorProto* msg); - static void set_has_options(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } }; -const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::_Internal::options(const ServiceDescriptorProto* msg) { - return *msg->_impl_.options_; -} ServiceDescriptorProto::ServiceDescriptorProto(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -6547,9 +6441,9 @@ ServiceDescriptorProto::ServiceDescriptorProto( from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.options_ = (cached_has_bits & 0x00000002u) - ? CreateMaybeMessage<::google::protobuf::ServiceOptions>(arena, *from._impl_.options_) - : nullptr; + _impl_.options_ = (cached_has_bits & 0x00000002u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::ServiceOptions>( + arena, *from._impl_.options_) + : nullptr; // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceDescriptorProto) } @@ -6579,12 +6473,13 @@ inline void ServiceDescriptorProto::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* ServiceDescriptorProto::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { ServiceDescriptorProto::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(ServiceDescriptorProto, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void ServiceDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceDescriptorProto) @@ -6628,6 +6523,9 @@ constexpr ::_pbi::TcParseTable<2, 3, 2, 51, 2> ServiceDescriptorProto::_table_ = offsetof(decltype(_table_), aux_entries), &_ServiceDescriptorProto_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::ServiceDescriptorProto>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional string name = 1; @@ -6688,8 +6586,7 @@ constexpr ::_pbi::TcParseTable<2, 3, 2, 51, 2> ServiceDescriptorProto::_table_ = // optional .google.protobuf.ServiceOptions options = 3; if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 3, _Internal::options(this), - _Internal::options(this).GetCachedSize(), target, stream); + 3, *_impl_.options_, _impl_.options_->GetCachedSize(), target, stream); } if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) { @@ -6734,9 +6631,10 @@ constexpr ::_pbi::TcParseTable<2, 3, 2, 51, 2> ServiceDescriptorProto::_table_ = } -void ServiceDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void ServiceDescriptorProto::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -6750,10 +6648,16 @@ void ServiceDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, cons _this->_internal_set_name(from._internal_name()); } if (cached_has_bits & 0x00000002u) { - _this->_internal_mutable_options()->::google::protobuf::ServiceOptions::MergeFrom( - from._internal_options()); + ABSL_DCHECK(from._impl_.options_ != nullptr); + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::ServiceOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -6773,9 +6677,6 @@ PROTOBUF_NOINLINE bool ServiceDescriptorProto::IsInitialized() const { return true; } -::_pbi::CachedSize* ServiceDescriptorProto::AccessCachedSize() const { - return &_impl_._cached_size_; -} void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -6788,9 +6689,9 @@ void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* PROTOBUF_RESTR } ::google::protobuf::Metadata ServiceDescriptorProto::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[12]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[12]); } // =================================================================== @@ -6799,30 +6700,8 @@ class MethodDescriptorProto::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_._has_bits_); - static void set_has_name(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_input_type(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_output_type(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static const ::google::protobuf::MethodOptions& options(const MethodDescriptorProto* msg); - static void set_has_options(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_client_streaming(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_server_streaming(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } }; -const ::google::protobuf::MethodOptions& MethodDescriptorProto::_Internal::options(const MethodDescriptorProto* msg) { - return *msg->_impl_.options_; -} MethodDescriptorProto::MethodDescriptorProto(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -6847,9 +6726,9 @@ MethodDescriptorProto::MethodDescriptorProto( from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.options_ = (cached_has_bits & 0x00000008u) - ? CreateMaybeMessage<::google::protobuf::MethodOptions>(arena, *from._impl_.options_) - : nullptr; + _impl_.options_ = (cached_has_bits & 0x00000008u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::MethodOptions>( + arena, *from._impl_.options_) + : nullptr; ::memcpy(reinterpret_cast(&_impl_) + offsetof(Impl_, client_streaming_), reinterpret_cast(&from._impl_) + @@ -6894,12 +6773,13 @@ inline void MethodDescriptorProto::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* MethodDescriptorProto::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { MethodDescriptorProto::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void MethodDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.MethodDescriptorProto) @@ -6951,6 +6831,9 @@ constexpr ::_pbi::TcParseTable<3, 6, 1, 71, 2> MethodDescriptorProto::_table_ = offsetof(decltype(_table_), aux_entries), &_MethodDescriptorProto_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::MethodDescriptorProto>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional string name = 1; @@ -7039,8 +6922,7 @@ constexpr ::_pbi::TcParseTable<3, 6, 1, 71, 2> MethodDescriptorProto::_table_ = // optional .google.protobuf.MethodOptions options = 4; if (cached_has_bits & 0x00000008u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 4, _Internal::options(this), - _Internal::options(this).GetCachedSize(), target, stream); + 4, *_impl_.options_, _impl_.options_->GetCachedSize(), target, stream); } // optional bool client_streaming = 5 [default = false]; @@ -7115,9 +6997,10 @@ constexpr ::_pbi::TcParseTable<3, 6, 1, 71, 2> MethodDescriptorProto::_table_ = } -void MethodDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void MethodDescriptorProto::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodDescriptorProto) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -7135,8 +7018,13 @@ void MethodDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const _this->_internal_set_output_type(from._internal_output_type()); } if (cached_has_bits & 0x00000008u) { - _this->_internal_mutable_options()->::google::protobuf::MethodOptions::MergeFrom( - from._internal_options()); + ABSL_DCHECK(from._impl_.options_ != nullptr); + if (_this->_impl_.options_ == nullptr) { + _this->_impl_.options_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::MethodOptions>(arena, *from._impl_.options_); + } else { + _this->_impl_.options_->MergeFrom(*from._impl_.options_); + } } if (cached_has_bits & 0x00000010u) { _this->_impl_.client_streaming_ = from._impl_.client_streaming_; @@ -7144,8 +7032,8 @@ void MethodDescriptorProto::MergeImpl(::google::protobuf::Message& to_msg, const if (cached_has_bits & 0x00000020u) { _this->_impl_.server_streaming_ = from._impl_.server_streaming_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -7163,9 +7051,6 @@ PROTOBUF_NOINLINE bool MethodDescriptorProto::IsInitialized() const { return true; } -::_pbi::CachedSize* MethodDescriptorProto::AccessCachedSize() const { - return &_impl_._cached_size_; -} void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -7184,9 +7069,9 @@ void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* PROTOBUF_RESTRIC } ::google::protobuf::Metadata MethodDescriptorProto::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[13]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[13]); } // =================================================================== @@ -7195,75 +7080,8 @@ class FileOptions::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FileOptions, _impl_._has_bits_); - static void set_has_java_package(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_java_outer_classname(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_java_multiple_files(HasBits* has_bits) { - (*has_bits)[0] |= 2048u; - } - static void set_has_java_generate_equals_and_hash(HasBits* has_bits) { - (*has_bits)[0] |= 4096u; - } - static void set_has_java_string_check_utf8(HasBits* has_bits) { - (*has_bits)[0] |= 8192u; - } - static void set_has_optimize_for(HasBits* has_bits) { - (*has_bits)[0] |= 524288u; - } - static void set_has_go_package(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_cc_generic_services(HasBits* has_bits) { - (*has_bits)[0] |= 16384u; - } - static void set_has_java_generic_services(HasBits* has_bits) { - (*has_bits)[0] |= 32768u; - } - static void set_has_py_generic_services(HasBits* has_bits) { - (*has_bits)[0] |= 65536u; - } - static void set_has_php_generic_services(HasBits* has_bits) { - (*has_bits)[0] |= 131072u; - } - static void set_has_deprecated(HasBits* has_bits) { - (*has_bits)[0] |= 262144u; - } - static void set_has_cc_enable_arenas(HasBits* has_bits) { - (*has_bits)[0] |= 1048576u; - } - static void set_has_objc_class_prefix(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_csharp_namespace(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_swift_prefix(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static void set_has_php_class_prefix(HasBits* has_bits) { - (*has_bits)[0] |= 64u; - } - static void set_has_php_namespace(HasBits* has_bits) { - (*has_bits)[0] |= 128u; - } - static void set_has_php_metadata_namespace(HasBits* has_bits) { - (*has_bits)[0] |= 256u; - } - static void set_has_ruby_package(HasBits* has_bits) { - (*has_bits)[0] |= 512u; - } - static const ::google::protobuf::FeatureSet& features(const FileOptions* msg); - static void set_has_features(HasBits* has_bits) { - (*has_bits)[0] |= 1024u; - } }; -const ::google::protobuf::FeatureSet& FileOptions::_Internal::features(const FileOptions* msg) { - return *msg->_impl_.features_; -} FileOptions::FileOptions(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -7298,9 +7116,9 @@ FileOptions::FileOptions( new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); _impl_._extensions_.MergeFrom(this, from._impl_._extensions_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.features_ = (cached_has_bits & 0x00000400u) - ? CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_) - : nullptr; + _impl_.features_ = (cached_has_bits & 0x00000400u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>( + arena, *from._impl_.features_) + : nullptr; ::memcpy(reinterpret_cast(&_impl_) + offsetof(Impl_, java_multiple_files_), reinterpret_cast(&from._impl_) + @@ -7363,12 +7181,13 @@ inline void FileOptions::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* FileOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { FileOptions::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(FileOptions, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void FileOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FileOptions) @@ -7454,6 +7273,9 @@ constexpr ::_pbi::TcParseTable<5, 22, 3, 202, 12> FileOptions::_table_ = { offsetof(decltype(_table_), aux_entries), &_FileOptions_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::FileOptions>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional string java_package = 1; @@ -7776,8 +7598,7 @@ constexpr ::_pbi::TcParseTable<5, 22, 3, 202, 12> FileOptions::_table_ = { // optional .google.protobuf.FeatureSet features = 50; if (cached_has_bits & 0x00000400u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 50, _Internal::features(this), - _Internal::features(this).GetCachedSize(), target, stream); + 50, *_impl_.features_, _impl_.features_->GetCachedSize(), target, stream); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; @@ -7944,9 +7765,10 @@ constexpr ::_pbi::TcParseTable<5, 22, 3, 202, 12> FileOptions::_table_ = { } -void FileOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void FileOptions::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -7989,8 +7811,13 @@ void FileOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google: _this->_internal_set_ruby_package(from._internal_ruby_package()); } if (cached_has_bits & 0x00000400u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + ABSL_DCHECK(from._impl_.features_ != nullptr); + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000800u) { _this->_impl_.java_multiple_files_ = from._impl_.java_multiple_files_; @@ -8007,7 +7834,6 @@ void FileOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google: if (cached_has_bits & 0x00008000u) { _this->_impl_.java_generic_services_ = from._impl_.java_generic_services_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } if (cached_has_bits & 0x001f0000u) { if (cached_has_bits & 0x00010000u) { @@ -8025,8 +7851,8 @@ void FileOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google: if (cached_has_bits & 0x00100000u) { _this->_impl_.cc_enable_arenas_ = from._impl_.cc_enable_arenas_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_); _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -8050,9 +7876,6 @@ PROTOBUF_NOINLINE bool FileOptions::IsInitialized() const { return true; } -::_pbi::CachedSize* FileOptions::AccessCachedSize() const { - return &_impl_._cached_size_; -} void FileOptions::InternalSwap(FileOptions* PROTOBUF_RESTRICT other) { using std::swap; _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); @@ -8080,9 +7903,9 @@ void FileOptions::InternalSwap(FileOptions* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata FileOptions::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[14]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[14]); } // =================================================================== @@ -8091,30 +7914,8 @@ class MessageOptions::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_._has_bits_); - static void set_has_message_set_wire_format(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_no_standard_descriptor_accessor(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_deprecated(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_map_entry(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_deprecated_legacy_json_field_conflicts(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static const ::google::protobuf::FeatureSet& features(const MessageOptions* msg); - static void set_has_features(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } }; -const ::google::protobuf::FeatureSet& MessageOptions::_Internal::features(const MessageOptions* msg) { - return *msg->_impl_.features_; -} MessageOptions::MessageOptions(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -8139,9 +7940,9 @@ MessageOptions::MessageOptions( new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); _impl_._extensions_.MergeFrom(this, from._impl_._extensions_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.features_ = (cached_has_bits & 0x00000001u) - ? CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_) - : nullptr; + _impl_.features_ = (cached_has_bits & 0x00000001u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>( + arena, *from._impl_.features_) + : nullptr; ::memcpy(reinterpret_cast(&_impl_) + offsetof(Impl_, message_set_wire_format_), reinterpret_cast(&from._impl_) + @@ -8182,12 +7983,13 @@ inline void MessageOptions::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* MessageOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { MessageOptions::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void MessageOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.MessageOptions) @@ -8232,6 +8034,9 @@ constexpr ::_pbi::TcParseTable<3, 7, 2, 0, 7> MessageOptions::_table_ = { offsetof(decltype(_table_), aux_entries), &_MessageOptions_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::MessageOptions>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional bool message_set_wire_format = 1 [default = false]; @@ -8330,8 +8135,7 @@ constexpr ::_pbi::TcParseTable<3, 7, 2, 0, 7> MessageOptions::_table_ = { // optional .google.protobuf.FeatureSet features = 12; if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 12, _Internal::features(this), - _Internal::features(this).GetCachedSize(), target, stream); + 12, *_impl_.features_, _impl_.features_->GetCachedSize(), target, stream); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; @@ -8408,9 +8212,10 @@ constexpr ::_pbi::TcParseTable<3, 7, 2, 0, 7> MessageOptions::_table_ = { } -void MessageOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void MessageOptions::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MessageOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -8421,8 +8226,13 @@ void MessageOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::goog cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x0000003fu) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + ABSL_DCHECK(from._impl_.features_ != nullptr); + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.message_set_wire_format_ = from._impl_.message_set_wire_format_; @@ -8439,8 +8249,8 @@ void MessageOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::goog if (cached_has_bits & 0x00000020u) { _this->_impl_.deprecated_legacy_json_field_conflicts_ = from._impl_.deprecated_legacy_json_field_conflicts_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_); _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -8464,9 +8274,6 @@ PROTOBUF_NOINLINE bool MessageOptions::IsInitialized() const { return true; } -::_pbi::CachedSize* MessageOptions::AccessCachedSize() const { - return &_impl_._cached_size_; -} void MessageOptions::InternalSwap(MessageOptions* PROTOBUF_RESTRICT other) { using std::swap; _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); @@ -8482,9 +8289,9 @@ void MessageOptions::InternalSwap(MessageOptions* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata MessageOptions::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[15]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[15]); } // =================================================================== @@ -8493,12 +8300,6 @@ class FieldOptions_EditionDefault::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FieldOptions_EditionDefault, _impl_._has_bits_); - static void set_has_edition(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_value(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } }; FieldOptions_EditionDefault::FieldOptions_EditionDefault(::google::protobuf::Arena* arena) @@ -8550,12 +8351,13 @@ inline void FieldOptions_EditionDefault::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* FieldOptions_EditionDefault::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { FieldOptions_EditionDefault::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(FieldOptions_EditionDefault, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void FieldOptions_EditionDefault::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FieldOptions.EditionDefault) @@ -8593,6 +8395,9 @@ constexpr ::_pbi::TcParseTable<1, 2, 1, 57, 2> FieldOptions_EditionDefault::_tab offsetof(decltype(_table_), aux_entries), &_FieldOptions_EditionDefault_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::FieldOptions_EditionDefault>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // optional string value = 2; {::_pbi::TcParser::FastSS1, @@ -8677,7 +8482,7 @@ constexpr ::_pbi::TcParseTable<1, 2, 1, 57, 2> FieldOptions_EditionDefault::_tab } -void FieldOptions_EditionDefault::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void FieldOptions_EditionDefault::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldOptions.EditionDefault) @@ -8693,8 +8498,8 @@ void FieldOptions_EditionDefault::MergeImpl(::google::protobuf::Message& to_msg, if (cached_has_bits & 0x00000002u) { _this->_impl_.edition_ = from._impl_.edition_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -8709,9 +8514,6 @@ PROTOBUF_NOINLINE bool FieldOptions_EditionDefault::IsInitialized() const { return true; } -::_pbi::CachedSize* FieldOptions_EditionDefault::AccessCachedSize() const { - return &_impl_._cached_size_; -} void FieldOptions_EditionDefault::InternalSwap(FieldOptions_EditionDefault* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -8723,9 +8525,9 @@ void FieldOptions_EditionDefault::InternalSwap(FieldOptions_EditionDefault* PROT } ::google::protobuf::Metadata FieldOptions_EditionDefault::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[16]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[16]); } // =================================================================== @@ -8734,42 +8536,8 @@ class FieldOptions::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_._has_bits_); - static void set_has_ctype(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_packed(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_jstype(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_lazy(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_unverified_lazy(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static void set_has_deprecated(HasBits* has_bits) { - (*has_bits)[0] |= 64u; - } - static void set_has_weak(HasBits* has_bits) { - (*has_bits)[0] |= 128u; - } - static void set_has_debug_redact(HasBits* has_bits) { - (*has_bits)[0] |= 256u; - } - static void set_has_retention(HasBits* has_bits) { - (*has_bits)[0] |= 512u; - } - static const ::google::protobuf::FeatureSet& features(const FieldOptions* msg); - static void set_has_features(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } }; -const ::google::protobuf::FeatureSet& FieldOptions::_Internal::features(const FieldOptions* msg) { - return *msg->_impl_.features_; -} FieldOptions::FieldOptions(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -8796,9 +8564,9 @@ FieldOptions::FieldOptions( new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); _impl_._extensions_.MergeFrom(this, from._impl_._extensions_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.features_ = (cached_has_bits & 0x00000001u) - ? CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_) - : nullptr; + _impl_.features_ = (cached_has_bits & 0x00000001u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>( + arena, *from._impl_.features_) + : nullptr; ::memcpy(reinterpret_cast(&_impl_) + offsetof(Impl_, ctype_), reinterpret_cast(&from._impl_) + @@ -8841,12 +8609,13 @@ inline void FieldOptions::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* FieldOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { FieldOptions::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void FieldOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FieldOptions) @@ -8898,6 +8667,9 @@ constexpr ::_pbi::TcParseTable<4, 13, 7, 0, 7> FieldOptions::_table_ = { offsetof(decltype(_table_), aux_entries), &_FieldOptions_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::FieldOptions>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // optional bool debug_redact = 16 [default = false]; {::_pbi::TcParser::FastV8S2, @@ -9081,8 +8853,7 @@ constexpr ::_pbi::TcParseTable<4, 13, 7, 0, 7> FieldOptions::_table_ = { // optional .google.protobuf.FeatureSet features = 21; if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 21, _Internal::features(this), - _Internal::features(this).GetCachedSize(), target, stream); + 21, *_impl_.features_, _impl_.features_->GetCachedSize(), target, stream); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; @@ -9202,9 +8973,10 @@ constexpr ::_pbi::TcParseTable<4, 13, 7, 0, 7> FieldOptions::_table_ = { } -void FieldOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void FieldOptions::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -9218,8 +8990,13 @@ void FieldOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x000000ffu) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + ABSL_DCHECK(from._impl_.features_ != nullptr); + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.ctype_ = from._impl_.ctype_; @@ -9242,7 +9019,6 @@ void FieldOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google if (cached_has_bits & 0x00000080u) { _this->_impl_.weak_ = from._impl_.weak_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } if (cached_has_bits & 0x00000300u) { if (cached_has_bits & 0x00000100u) { @@ -9251,8 +9027,8 @@ void FieldOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google if (cached_has_bits & 0x00000200u) { _this->_impl_.retention_ = from._impl_.retention_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_); _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -9276,9 +9052,6 @@ PROTOBUF_NOINLINE bool FieldOptions::IsInitialized() const { return true; } -::_pbi::CachedSize* FieldOptions::AccessCachedSize() const { - return &_impl_._cached_size_; -} void FieldOptions::InternalSwap(FieldOptions* PROTOBUF_RESTRICT other) { using std::swap; _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); @@ -9296,9 +9069,9 @@ void FieldOptions::InternalSwap(FieldOptions* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata FieldOptions::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[17]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[17]); } // =================================================================== @@ -9307,15 +9080,8 @@ class OneofOptions::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(OneofOptions, _impl_._has_bits_); - static const ::google::protobuf::FeatureSet& features(const OneofOptions* msg); - static void set_has_features(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } }; -const ::google::protobuf::FeatureSet& OneofOptions::_Internal::features(const OneofOptions* msg) { - return *msg->_impl_.features_; -} OneofOptions::OneofOptions(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -9340,9 +9106,9 @@ OneofOptions::OneofOptions( new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); _impl_._extensions_.MergeFrom(this, from._impl_._extensions_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.features_ = (cached_has_bits & 0x00000001u) - ? CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_) - : nullptr; + _impl_.features_ = (cached_has_bits & 0x00000001u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>( + arena, *from._impl_.features_) + : nullptr; // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofOptions) } @@ -9371,12 +9137,13 @@ inline void OneofOptions::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* OneofOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { OneofOptions::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(OneofOptions, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void OneofOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.OneofOptions) @@ -9416,6 +9183,9 @@ constexpr ::_pbi::TcParseTable<2, 2, 2, 0, 7> OneofOptions::_table_ = { offsetof(decltype(_table_), aux_entries), &_OneofOptions_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::OneofOptions>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional .google.protobuf.FeatureSet features = 1; @@ -9454,8 +9224,7 @@ constexpr ::_pbi::TcParseTable<2, 2, 2, 0, 7> OneofOptions::_table_ = { // optional .google.protobuf.FeatureSet features = 1; if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 1, _Internal::features(this), - _Internal::features(this).GetCachedSize(), target, stream); + 1, *_impl_.features_, _impl_.features_->GetCachedSize(), target, stream); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; @@ -9505,9 +9274,10 @@ constexpr ::_pbi::TcParseTable<2, 2, 2, 0, 7> OneofOptions::_table_ = { } -void OneofOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void OneofOptions::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -9515,10 +9285,17 @@ void OneofOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google _this->_internal_mutable_uninterpreted_option()->MergeFrom( from._internal_uninterpreted_option()); - if ((from._impl_._has_bits_[0] & 0x00000001u) != 0) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + cached_has_bits = from._impl_._has_bits_[0]; + if (cached_has_bits & 0x00000001u) { + ABSL_DCHECK(from._impl_.features_ != nullptr); + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_); _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -9542,9 +9319,6 @@ PROTOBUF_NOINLINE bool OneofOptions::IsInitialized() const { return true; } -::_pbi::CachedSize* OneofOptions::AccessCachedSize() const { - return &_impl_._cached_size_; -} void OneofOptions::InternalSwap(OneofOptions* PROTOBUF_RESTRICT other) { using std::swap; _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); @@ -9555,9 +9329,9 @@ void OneofOptions::InternalSwap(OneofOptions* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata OneofOptions::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[18]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[18]); } // =================================================================== @@ -9566,24 +9340,8 @@ class EnumOptions::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_._has_bits_); - static void set_has_allow_alias(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_deprecated(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_deprecated_legacy_json_field_conflicts(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static const ::google::protobuf::FeatureSet& features(const EnumOptions* msg); - static void set_has_features(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } }; -const ::google::protobuf::FeatureSet& EnumOptions::_Internal::features(const EnumOptions* msg) { - return *msg->_impl_.features_; -} EnumOptions::EnumOptions(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -9608,9 +9366,9 @@ EnumOptions::EnumOptions( new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); _impl_._extensions_.MergeFrom(this, from._impl_._extensions_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.features_ = (cached_has_bits & 0x00000001u) - ? CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_) - : nullptr; + _impl_.features_ = (cached_has_bits & 0x00000001u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>( + arena, *from._impl_.features_) + : nullptr; ::memcpy(reinterpret_cast(&_impl_) + offsetof(Impl_, allow_alias_), reinterpret_cast(&from._impl_) + @@ -9651,12 +9409,13 @@ inline void EnumOptions::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* EnumOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { EnumOptions::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void EnumOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumOptions) @@ -9699,6 +9458,9 @@ constexpr ::_pbi::TcParseTable<3, 5, 2, 0, 7> EnumOptions::_table_ = { offsetof(decltype(_table_), aux_entries), &_EnumOptions_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::EnumOptions>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, {::_pbi::TcParser::MiniParse, {}}, @@ -9775,8 +9537,7 @@ constexpr ::_pbi::TcParseTable<3, 5, 2, 0, 7> EnumOptions::_table_ = { // optional .google.protobuf.FeatureSet features = 7; if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 7, _Internal::features(this), - _Internal::features(this).GetCachedSize(), target, stream); + 7, *_impl_.features_, _impl_.features_->GetCachedSize(), target, stream); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; @@ -9843,9 +9604,10 @@ constexpr ::_pbi::TcParseTable<3, 5, 2, 0, 7> EnumOptions::_table_ = { } -void EnumOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void EnumOptions::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -9856,8 +9618,13 @@ void EnumOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google: cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x0000000fu) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + ABSL_DCHECK(from._impl_.features_ != nullptr); + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.allow_alias_ = from._impl_.allow_alias_; @@ -9868,8 +9635,8 @@ void EnumOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google: if (cached_has_bits & 0x00000008u) { _this->_impl_.deprecated_legacy_json_field_conflicts_ = from._impl_.deprecated_legacy_json_field_conflicts_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_); _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -9893,9 +9660,6 @@ PROTOBUF_NOINLINE bool EnumOptions::IsInitialized() const { return true; } -::_pbi::CachedSize* EnumOptions::AccessCachedSize() const { - return &_impl_._cached_size_; -} void EnumOptions::InternalSwap(EnumOptions* PROTOBUF_RESTRICT other) { using std::swap; _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); @@ -9911,9 +9675,9 @@ void EnumOptions::InternalSwap(EnumOptions* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata EnumOptions::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[19]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[19]); } // =================================================================== @@ -9922,21 +9686,8 @@ class EnumValueOptions::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_._has_bits_); - static void set_has_deprecated(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static const ::google::protobuf::FeatureSet& features(const EnumValueOptions* msg); - static void set_has_features(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_debug_redact(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } }; -const ::google::protobuf::FeatureSet& EnumValueOptions::_Internal::features(const EnumValueOptions* msg) { - return *msg->_impl_.features_; -} EnumValueOptions::EnumValueOptions(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -9961,9 +9712,9 @@ EnumValueOptions::EnumValueOptions( new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); _impl_._extensions_.MergeFrom(this, from._impl_._extensions_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.features_ = (cached_has_bits & 0x00000001u) - ? CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_) - : nullptr; + _impl_.features_ = (cached_has_bits & 0x00000001u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>( + arena, *from._impl_.features_) + : nullptr; ::memcpy(reinterpret_cast(&_impl_) + offsetof(Impl_, deprecated_), reinterpret_cast(&from._impl_) + @@ -10004,12 +9755,13 @@ inline void EnumValueOptions::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* EnumValueOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { EnumValueOptions::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void EnumValueOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueOptions) @@ -10052,6 +9804,9 @@ constexpr ::_pbi::TcParseTable<3, 4, 2, 0, 7> EnumValueOptions::_table_ = { offsetof(decltype(_table_), aux_entries), &_EnumValueOptions_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::EnumValueOptions>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional bool deprecated = 1 [default = false]; @@ -10111,8 +9866,7 @@ constexpr ::_pbi::TcParseTable<3, 4, 2, 0, 7> EnumValueOptions::_table_ = { // optional .google.protobuf.FeatureSet features = 2; if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 2, _Internal::features(this), - _Internal::features(this).GetCachedSize(), target, stream); + 2, *_impl_.features_, _impl_.features_->GetCachedSize(), target, stream); } // optional bool debug_redact = 3 [default = false]; @@ -10181,9 +9935,10 @@ constexpr ::_pbi::TcParseTable<3, 4, 2, 0, 7> EnumValueOptions::_table_ = { } -void EnumValueOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void EnumValueOptions::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -10194,8 +9949,13 @@ void EnumValueOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::go cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000007u) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + ABSL_DCHECK(from._impl_.features_ != nullptr); + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.deprecated_ = from._impl_.deprecated_; @@ -10203,8 +9963,8 @@ void EnumValueOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::go if (cached_has_bits & 0x00000004u) { _this->_impl_.debug_redact_ = from._impl_.debug_redact_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_); _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -10228,9 +9988,6 @@ PROTOBUF_NOINLINE bool EnumValueOptions::IsInitialized() const { return true; } -::_pbi::CachedSize* EnumValueOptions::AccessCachedSize() const { - return &_impl_._cached_size_; -} void EnumValueOptions::InternalSwap(EnumValueOptions* PROTOBUF_RESTRICT other) { using std::swap; _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); @@ -10246,9 +10003,9 @@ void EnumValueOptions::InternalSwap(EnumValueOptions* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata EnumValueOptions::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[20]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[20]); } // =================================================================== @@ -10257,18 +10014,8 @@ class ServiceOptions::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_._has_bits_); - static const ::google::protobuf::FeatureSet& features(const ServiceOptions* msg); - static void set_has_features(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_deprecated(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } }; -const ::google::protobuf::FeatureSet& ServiceOptions::_Internal::features(const ServiceOptions* msg) { - return *msg->_impl_.features_; -} ServiceOptions::ServiceOptions(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -10293,9 +10040,9 @@ ServiceOptions::ServiceOptions( new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); _impl_._extensions_.MergeFrom(this, from._impl_._extensions_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.features_ = (cached_has_bits & 0x00000001u) - ? CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_) - : nullptr; + _impl_.features_ = (cached_has_bits & 0x00000001u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>( + arena, *from._impl_.features_) + : nullptr; _impl_.deprecated_ = from._impl_.deprecated_; // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceOptions) @@ -10330,12 +10077,13 @@ inline void ServiceOptions::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* ServiceOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { ServiceOptions::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void ServiceOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceOptions) @@ -10376,6 +10124,9 @@ constexpr ::_pbi::TcParseTable<2, 3, 2, 0, 12> ServiceOptions::_table_ = { offsetof(decltype(_table_), aux_entries), &_ServiceOptions_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::ServiceOptions>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional bool deprecated = 33 [default = false]; @@ -10427,8 +10178,7 @@ constexpr ::_pbi::TcParseTable<2, 3, 2, 0, 12> ServiceOptions::_table_ = { // optional .google.protobuf.FeatureSet features = 34; if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 34, _Internal::features(this), - _Internal::features(this).GetCachedSize(), target, stream); + 34, *_impl_.features_, _impl_.features_->GetCachedSize(), target, stream); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; @@ -10485,9 +10235,10 @@ constexpr ::_pbi::TcParseTable<2, 3, 2, 0, 12> ServiceOptions::_table_ = { } -void ServiceOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void ServiceOptions::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -10498,14 +10249,19 @@ void ServiceOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::goog cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000003u) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + ABSL_DCHECK(from._impl_.features_ != nullptr); + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.deprecated_ = from._impl_.deprecated_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_); _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -10529,9 +10285,6 @@ PROTOBUF_NOINLINE bool ServiceOptions::IsInitialized() const { return true; } -::_pbi::CachedSize* ServiceOptions::AccessCachedSize() const { - return &_impl_._cached_size_; -} void ServiceOptions::InternalSwap(ServiceOptions* PROTOBUF_RESTRICT other) { using std::swap; _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); @@ -10547,9 +10300,9 @@ void ServiceOptions::InternalSwap(ServiceOptions* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata ServiceOptions::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[21]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[21]); } // =================================================================== @@ -10558,21 +10311,8 @@ class MethodOptions::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_._has_bits_); - static void set_has_deprecated(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_idempotency_level(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static const ::google::protobuf::FeatureSet& features(const MethodOptions* msg); - static void set_has_features(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } }; -const ::google::protobuf::FeatureSet& MethodOptions::_Internal::features(const MethodOptions* msg) { - return *msg->_impl_.features_; -} MethodOptions::MethodOptions(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -10597,9 +10337,9 @@ MethodOptions::MethodOptions( new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); _impl_._extensions_.MergeFrom(this, from._impl_._extensions_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.features_ = (cached_has_bits & 0x00000001u) - ? CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_) - : nullptr; + _impl_.features_ = (cached_has_bits & 0x00000001u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>( + arena, *from._impl_.features_) + : nullptr; ::memcpy(reinterpret_cast(&_impl_) + offsetof(Impl_, deprecated_), reinterpret_cast(&from._impl_) + @@ -10640,12 +10380,13 @@ inline void MethodOptions::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* MethodOptions::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { MethodOptions::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void MethodOptions::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.MethodOptions) @@ -10690,6 +10431,9 @@ constexpr ::_pbi::TcParseTable<3, 4, 3, 0, 12> MethodOptions::_table_ = { offsetof(decltype(_table_), aux_entries), &_MethodOptions_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::MethodOptions>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional bool deprecated = 33 [default = false]; @@ -10758,8 +10502,7 @@ constexpr ::_pbi::TcParseTable<3, 4, 3, 0, 12> MethodOptions::_table_ = { // optional .google.protobuf.FeatureSet features = 35; if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 35, _Internal::features(this), - _Internal::features(this).GetCachedSize(), target, stream); + 35, *_impl_.features_, _impl_.features_->GetCachedSize(), target, stream); } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; @@ -10822,9 +10565,10 @@ constexpr ::_pbi::TcParseTable<3, 4, 3, 0, 12> MethodOptions::_table_ = { } -void MethodOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void MethodOptions::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodOptions) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -10835,8 +10579,13 @@ void MethodOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::googl cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000007u) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + ABSL_DCHECK(from._impl_.features_ != nullptr); + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.deprecated_ = from._impl_.deprecated_; @@ -10844,8 +10593,8 @@ void MethodOptions::MergeImpl(::google::protobuf::Message& to_msg, const ::googl if (cached_has_bits & 0x00000004u) { _this->_impl_.idempotency_level_ = from._impl_.idempotency_level_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_); _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -10869,9 +10618,6 @@ PROTOBUF_NOINLINE bool MethodOptions::IsInitialized() const { return true; } -::_pbi::CachedSize* MethodOptions::AccessCachedSize() const { - return &_impl_._cached_size_; -} void MethodOptions::InternalSwap(MethodOptions* PROTOBUF_RESTRICT other) { using std::swap; _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); @@ -10887,9 +10633,9 @@ void MethodOptions::InternalSwap(MethodOptions* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata MethodOptions::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[22]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[22]); } // =================================================================== @@ -10898,12 +10644,6 @@ class UninterpretedOption_NamePart::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(UninterpretedOption_NamePart, _impl_._has_bits_); - static void set_has_name_part(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_is_extension(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } static bool MissingRequiredFields(const HasBits& has_bits) { return ((has_bits[0] & 0x00000003) ^ 0x00000003) != 0; } @@ -10958,12 +10698,13 @@ inline void UninterpretedOption_NamePart::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* UninterpretedOption_NamePart::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { UninterpretedOption_NamePart::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(UninterpretedOption_NamePart, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void UninterpretedOption_NamePart::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption.NamePart) @@ -11001,6 +10742,9 @@ constexpr ::_pbi::TcParseTable<1, 2, 0, 62, 2> UninterpretedOption_NamePart::_ta offsetof(decltype(_table_), field_names), // no aux_entries &_UninterpretedOption_NamePart_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::UninterpretedOption_NamePart>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // required bool is_extension = 2; {::_pbi::TcParser::SingularVarintNoZag1(), @@ -11084,7 +10828,7 @@ constexpr ::_pbi::TcParseTable<1, 2, 0, 62, 2> UninterpretedOption_NamePart::_ta } -void UninterpretedOption_NamePart::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void UninterpretedOption_NamePart::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption.NamePart) @@ -11100,8 +10844,8 @@ void UninterpretedOption_NamePart::MergeImpl(::google::protobuf::Message& to_msg if (cached_has_bits & 0x00000002u) { _this->_impl_.is_extension_ = from._impl_.is_extension_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -11119,9 +10863,6 @@ PROTOBUF_NOINLINE bool UninterpretedOption_NamePart::IsInitialized() const { return true; } -::_pbi::CachedSize* UninterpretedOption_NamePart::AccessCachedSize() const { - return &_impl_._cached_size_; -} void UninterpretedOption_NamePart::InternalSwap(UninterpretedOption_NamePart* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -11133,9 +10874,9 @@ void UninterpretedOption_NamePart::InternalSwap(UninterpretedOption_NamePart* PR } ::google::protobuf::Metadata UninterpretedOption_NamePart::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[23]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[23]); } // =================================================================== @@ -11144,24 +10885,6 @@ class UninterpretedOption::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_._has_bits_); - static void set_has_identifier_value(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_positive_int_value(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_negative_int_value(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_double_value(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } - static void set_has_string_value(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_aggregate_value(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } }; UninterpretedOption::UninterpretedOption(::google::protobuf::Arena* arena) @@ -11232,12 +10955,13 @@ inline void UninterpretedOption::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* UninterpretedOption::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { UninterpretedOption::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void UninterpretedOption::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption) @@ -11288,6 +11012,9 @@ constexpr ::_pbi::TcParseTable<3, 7, 1, 75, 2> UninterpretedOption::_table_ = { offsetof(decltype(_table_), aux_entries), &_UninterpretedOption_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::UninterpretedOption>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // optional string aggregate_value = 8; {::_pbi::TcParser::FastSS1, @@ -11469,7 +11196,7 @@ constexpr ::_pbi::TcParseTable<3, 7, 1, 75, 2> UninterpretedOption::_table_ = { } -void UninterpretedOption::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void UninterpretedOption::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption) @@ -11499,8 +11226,8 @@ void UninterpretedOption::MergeImpl(::google::protobuf::Message& to_msg, const : if (cached_has_bits & 0x00000020u) { _this->_impl_.double_value_ = from._impl_.double_value_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -11517,9 +11244,6 @@ PROTOBUF_NOINLINE bool UninterpretedOption::IsInitialized() const { return true; } -::_pbi::CachedSize* UninterpretedOption::AccessCachedSize() const { - return &_impl_._cached_size_; -} void UninterpretedOption::InternalSwap(UninterpretedOption* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -11539,9 +11263,9 @@ void UninterpretedOption::InternalSwap(UninterpretedOption* PROTOBUF_RESTRICT ot } ::google::protobuf::Metadata UninterpretedOption::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[24]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[24]); } // =================================================================== @@ -11550,24 +11274,6 @@ class FeatureSet::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_._has_bits_); - static void set_has_field_presence(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_enum_type(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_repeated_field_encoding(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_utf8_validation(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } - static void set_has_message_encoding(HasBits* has_bits) { - (*has_bits)[0] |= 16u; - } - static void set_has_json_format(HasBits* has_bits) { - (*has_bits)[0] |= 32u; - } }; FeatureSet::FeatureSet(::google::protobuf::Arena* arena) @@ -11630,12 +11336,13 @@ inline void FeatureSet::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* FeatureSet::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { FeatureSet::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void FeatureSet::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FeatureSet) @@ -11675,6 +11382,9 @@ constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { offsetof(decltype(_table_), aux_entries), &_FeatureSet_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::FeatureSet>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional .google.protobuf.FeatureSet.FieldPresence field_presence = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { @@ -11687,8 +11397,8 @@ constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { {::_pbi::TcParser::FastEr0S1, {24, 2, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.repeated_field_encoding_)}}, // optional .google.protobuf.FeatureSet.Utf8Validation utf8_validation = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { - {::_pbi::TcParser::FastEr0S1, - {32, 3, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.utf8_validation_)}}, + {::_pbi::TcParser::FastEvS1, + {32, 3, 3, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.utf8_validation_)}}, // optional .google.protobuf.FeatureSet.MessageEncoding message_encoding = 5 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { {::_pbi::TcParser::FastEr0S1, {40, 4, 2, PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.message_encoding_)}}, @@ -11710,7 +11420,7 @@ constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, // optional .google.protobuf.FeatureSet.Utf8Validation utf8_validation = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.utf8_validation_), _Internal::kHasBitsOffset + 3, 3, - (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, + (0 | ::_fl::kFcOptional | ::_fl::kEnum)}, // optional .google.protobuf.FeatureSet.MessageEncoding message_encoding = 5 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { {PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.message_encoding_), _Internal::kHasBitsOffset + 4, 4, (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, @@ -11721,7 +11431,7 @@ constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { {0, 4}, {0, 3}, {0, 3}, - {0, 3}, + {::_pbi::FieldAuxEnumData{}, ::google::protobuf::FeatureSet_Utf8Validation_internal_data_}, {0, 3}, {0, 3}, }}, {{ @@ -11843,7 +11553,7 @@ constexpr ::_pbi::TcParseTable<3, 6, 6, 0, 2> FeatureSet::_table_ = { } -void FeatureSet::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void FeatureSet::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FeatureSet) @@ -11871,8 +11581,8 @@ void FeatureSet::MergeImpl(::google::protobuf::Message& to_msg, const ::google:: if (cached_has_bits & 0x00000020u) { _this->_impl_.json_format_ = from._impl_.json_format_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_impl_._extensions_.MergeFrom(internal_default_instance(), from._impl_._extensions_); _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -11891,9 +11601,6 @@ PROTOBUF_NOINLINE bool FeatureSet::IsInitialized() const { return true; } -::_pbi::CachedSize* FeatureSet::AccessCachedSize() const { - return &_impl_._cached_size_; -} void FeatureSet::InternalSwap(FeatureSet* PROTOBUF_RESTRICT other) { using std::swap; _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); @@ -11908,9 +11615,9 @@ void FeatureSet::InternalSwap(FeatureSet* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata FeatureSet::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[25]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[25]); } // =================================================================== @@ -11919,18 +11626,8 @@ class FeatureSetDefaults_FeatureSetEditionDefault::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefault, _impl_._has_bits_); - static void set_has_edition(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static const ::google::protobuf::FeatureSet& features(const FeatureSetDefaults_FeatureSetEditionDefault* msg); - static void set_has_features(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } }; -const ::google::protobuf::FeatureSet& FeatureSetDefaults_FeatureSetEditionDefault::_Internal::features(const FeatureSetDefaults_FeatureSetEditionDefault* msg) { - return *msg->_impl_.features_; -} FeatureSetDefaults_FeatureSetEditionDefault::FeatureSetDefaults_FeatureSetEditionDefault(::google::protobuf::Arena* arena) : ::google::protobuf::Message(arena) { SharedCtor(arena); @@ -11952,9 +11649,9 @@ FeatureSetDefaults_FeatureSetEditionDefault::FeatureSetDefaults_FeatureSetEditio from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.features_ = (cached_has_bits & 0x00000001u) - ? CreateMaybeMessage<::google::protobuf::FeatureSet>(arena, *from._impl_.features_) - : nullptr; + _impl_.features_ = (cached_has_bits & 0x00000001u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>( + arena, *from._impl_.features_) + : nullptr; _impl_.edition_ = from._impl_.edition_; // @@protoc_insertion_point(copy_constructor:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault) @@ -11987,12 +11684,13 @@ inline void FeatureSetDefaults_FeatureSetEditionDefault::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* FeatureSetDefaults_FeatureSetEditionDefault::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefault, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void FeatureSetDefaults_FeatureSetEditionDefault::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault) @@ -12031,6 +11729,9 @@ constexpr ::_pbi::TcParseTable<1, 2, 2, 0, 2> FeatureSetDefaults_FeatureSetEditi offsetof(decltype(_table_), aux_entries), &_FeatureSetDefaults_FeatureSetEditionDefault_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // optional .google.protobuf.FeatureSet features = 2; {::_pbi::TcParser::FastMtS1, @@ -12065,8 +11766,7 @@ constexpr ::_pbi::TcParseTable<1, 2, 2, 0, 2> FeatureSetDefaults_FeatureSetEditi // optional .google.protobuf.FeatureSet features = 2; if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 2, _Internal::features(this), - _Internal::features(this).GetCachedSize(), target, stream); + 2, *_impl_.features_, _impl_.features_->GetCachedSize(), target, stream); } // optional .google.protobuf.Edition edition = 3; @@ -12112,9 +11812,10 @@ constexpr ::_pbi::TcParseTable<1, 2, 2, 0, 2> FeatureSetDefaults_FeatureSetEditi } -void FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -12123,14 +11824,19 @@ void FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl(::google::protobuf:: cached_has_bits = from._impl_._has_bits_[0]; if (cached_has_bits & 0x00000003u) { if (cached_has_bits & 0x00000001u) { - _this->_internal_mutable_features()->::google::protobuf::FeatureSet::MergeFrom( - from._internal_features()); + ABSL_DCHECK(from._impl_.features_ != nullptr); + if (_this->_impl_.features_ == nullptr) { + _this->_impl_.features_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::FeatureSet>(arena, *from._impl_.features_); + } else { + _this->_impl_.features_->MergeFrom(*from._impl_.features_); + } } if (cached_has_bits & 0x00000002u) { _this->_impl_.edition_ = from._impl_.edition_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -12148,9 +11854,6 @@ PROTOBUF_NOINLINE bool FeatureSetDefaults_FeatureSetEditionDefault::IsInitialize return true; } -::_pbi::CachedSize* FeatureSetDefaults_FeatureSetEditionDefault::AccessCachedSize() const { - return &_impl_._cached_size_; -} void FeatureSetDefaults_FeatureSetEditionDefault::InternalSwap(FeatureSetDefaults_FeatureSetEditionDefault* PROTOBUF_RESTRICT other) { using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); @@ -12164,9 +11867,9 @@ void FeatureSetDefaults_FeatureSetEditionDefault::InternalSwap(FeatureSetDefault } ::google::protobuf::Metadata FeatureSetDefaults_FeatureSetEditionDefault::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[26]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[26]); } // =================================================================== @@ -12175,12 +11878,6 @@ class FeatureSetDefaults::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FeatureSetDefaults, _impl_._has_bits_); - static void set_has_minimum_edition(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_maximum_edition(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } }; FeatureSetDefaults::FeatureSetDefaults(::google::protobuf::Arena* arena) @@ -12242,12 +11939,13 @@ inline void FeatureSetDefaults::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* FeatureSetDefaults::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { FeatureSetDefaults::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(FeatureSetDefaults, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void FeatureSetDefaults::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FeatureSetDefaults) @@ -12287,6 +11985,9 @@ constexpr ::_pbi::TcParseTable<1, 3, 3, 0, 2> FeatureSetDefaults::_table_ = { offsetof(decltype(_table_), aux_entries), &_FeatureSetDefaults_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::FeatureSetDefaults>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // optional .google.protobuf.Edition minimum_edition = 4; {::_pbi::TcParser::FastEvS1, @@ -12386,7 +12087,7 @@ constexpr ::_pbi::TcParseTable<1, 3, 3, 0, 2> FeatureSetDefaults::_table_ = { } -void FeatureSetDefaults::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void FeatureSetDefaults::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FeatureSetDefaults) @@ -12404,8 +12105,8 @@ void FeatureSetDefaults::MergeImpl(::google::protobuf::Message& to_msg, const :: if (cached_has_bits & 0x00000002u) { _this->_impl_.maximum_edition_ = from._impl_.maximum_edition_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -12422,9 +12123,6 @@ PROTOBUF_NOINLINE bool FeatureSetDefaults::IsInitialized() const { return true; } -::_pbi::CachedSize* FeatureSetDefaults::AccessCachedSize() const { - return &_impl_._cached_size_; -} void FeatureSetDefaults::InternalSwap(FeatureSetDefaults* PROTOBUF_RESTRICT other) { using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); @@ -12439,9 +12137,9 @@ void FeatureSetDefaults::InternalSwap(FeatureSetDefaults* PROTOBUF_RESTRICT othe } ::google::protobuf::Metadata FeatureSetDefaults::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[27]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[27]); } // =================================================================== @@ -12450,12 +12148,6 @@ class SourceCodeInfo_Location::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(SourceCodeInfo_Location, _impl_._has_bits_); - static void set_has_leading_comments(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_trailing_comments(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } }; SourceCodeInfo_Location::SourceCodeInfo_Location(::google::protobuf::Arena* arena) @@ -12518,12 +12210,13 @@ inline void SourceCodeInfo_Location::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* SourceCodeInfo_Location::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { SourceCodeInfo_Location::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(SourceCodeInfo_Location, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void SourceCodeInfo_Location::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo.Location) @@ -12568,6 +12261,9 @@ constexpr ::_pbi::TcParseTable<3, 5, 0, 106, 2> SourceCodeInfo_Location::_table_ offsetof(decltype(_table_), field_names), // no aux_entries &_SourceCodeInfo_Location_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::SourceCodeInfo_Location>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // repeated int32 path = 1 [packed = true]; @@ -12734,7 +12430,7 @@ constexpr ::_pbi::TcParseTable<3, 5, 0, 106, 2> SourceCodeInfo_Location::_table_ } -void SourceCodeInfo_Location::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void SourceCodeInfo_Location::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo.Location) @@ -12754,6 +12450,7 @@ void SourceCodeInfo_Location::MergeImpl(::google::protobuf::Message& to_msg, con _this->_internal_set_trailing_comments(from._internal_trailing_comments()); } } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -12768,9 +12465,6 @@ PROTOBUF_NOINLINE bool SourceCodeInfo_Location::IsInitialized() const { return true; } -::_pbi::CachedSize* SourceCodeInfo_Location::AccessCachedSize() const { - return &_impl_._cached_size_; -} void SourceCodeInfo_Location::InternalSwap(SourceCodeInfo_Location* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -12785,9 +12479,9 @@ void SourceCodeInfo_Location::InternalSwap(SourceCodeInfo_Location* PROTOBUF_RES } ::google::protobuf::Metadata SourceCodeInfo_Location::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[28]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[28]); } // =================================================================== @@ -12840,12 +12534,13 @@ inline void SourceCodeInfo::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* SourceCodeInfo::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { SourceCodeInfo::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(SourceCodeInfo, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void SourceCodeInfo::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo) @@ -12878,6 +12573,9 @@ constexpr ::_pbi::TcParseTable<0, 1, 1, 0, 2> SourceCodeInfo::_table_ = { offsetof(decltype(_table_), aux_entries), &_SourceCodeInfo_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::SourceCodeInfo>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // repeated .google.protobuf.SourceCodeInfo.Location location = 1; {::_pbi::TcParser::FastMtR1, @@ -12936,7 +12634,7 @@ constexpr ::_pbi::TcParseTable<0, 1, 1, 0, 2> SourceCodeInfo::_table_ = { } -void SourceCodeInfo::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void SourceCodeInfo::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo) @@ -12960,9 +12658,6 @@ PROTOBUF_NOINLINE bool SourceCodeInfo::IsInitialized() const { return true; } -::_pbi::CachedSize* SourceCodeInfo::AccessCachedSize() const { - return &_impl_._cached_size_; -} void SourceCodeInfo::InternalSwap(SourceCodeInfo* PROTOBUF_RESTRICT other) { using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); @@ -12970,9 +12665,9 @@ void SourceCodeInfo::InternalSwap(SourceCodeInfo* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata SourceCodeInfo::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[29]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[29]); } // =================================================================== @@ -12981,18 +12676,6 @@ class GeneratedCodeInfo_Annotation::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_._has_bits_); - static void set_has_source_file(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } - static void set_has_begin(HasBits* has_bits) { - (*has_bits)[0] |= 2u; - } - static void set_has_end(HasBits* has_bits) { - (*has_bits)[0] |= 4u; - } - static void set_has_semantic(HasBits* has_bits) { - (*has_bits)[0] |= 8u; - } }; GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(::google::protobuf::Arena* arena) @@ -13059,12 +12742,13 @@ inline void GeneratedCodeInfo_Annotation::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* GeneratedCodeInfo_Annotation::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { GeneratedCodeInfo_Annotation::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void GeneratedCodeInfo_Annotation::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo.Annotation) @@ -13107,6 +12791,9 @@ constexpr ::_pbi::TcParseTable<3, 5, 1, 64, 2> GeneratedCodeInfo_Annotation::_ta offsetof(decltype(_table_), aux_entries), &_GeneratedCodeInfo_Annotation_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::GeneratedCodeInfo_Annotation>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // repeated int32 path = 1 [packed = true]; @@ -13260,7 +12947,7 @@ constexpr ::_pbi::TcParseTable<3, 5, 1, 64, 2> GeneratedCodeInfo_Annotation::_ta } -void GeneratedCodeInfo_Annotation::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void GeneratedCodeInfo_Annotation::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo.Annotation) @@ -13283,8 +12970,8 @@ void GeneratedCodeInfo_Annotation::MergeImpl(::google::protobuf::Message& to_msg if (cached_has_bits & 0x00000008u) { _this->_impl_.semantic_ = from._impl_.semantic_; } - _this->_impl_._has_bits_[0] |= cached_has_bits; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -13299,9 +12986,6 @@ PROTOBUF_NOINLINE bool GeneratedCodeInfo_Annotation::IsInitialized() const { return true; } -::_pbi::CachedSize* GeneratedCodeInfo_Annotation::AccessCachedSize() const { - return &_impl_._cached_size_; -} void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -13319,9 +13003,9 @@ void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* PR } ::google::protobuf::Metadata GeneratedCodeInfo_Annotation::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[30]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[30]); } // =================================================================== @@ -13374,12 +13058,13 @@ inline void GeneratedCodeInfo::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* GeneratedCodeInfo::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { GeneratedCodeInfo::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void GeneratedCodeInfo::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo) @@ -13412,6 +13097,9 @@ constexpr ::_pbi::TcParseTable<0, 1, 1, 0, 2> GeneratedCodeInfo::_table_ = { offsetof(decltype(_table_), aux_entries), &_GeneratedCodeInfo_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::GeneratedCodeInfo>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; {::_pbi::TcParser::FastMtR1, @@ -13470,7 +13158,7 @@ constexpr ::_pbi::TcParseTable<0, 1, 1, 0, 2> GeneratedCodeInfo::_table_ = { } -void GeneratedCodeInfo::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void GeneratedCodeInfo::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo) @@ -13494,9 +13182,6 @@ PROTOBUF_NOINLINE bool GeneratedCodeInfo::IsInitialized() const { return true; } -::_pbi::CachedSize* GeneratedCodeInfo::AccessCachedSize() const { - return &_impl_._cached_size_; -} void GeneratedCodeInfo::InternalSwap(GeneratedCodeInfo* PROTOBUF_RESTRICT other) { using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); @@ -13504,9 +13189,9 @@ void GeneratedCodeInfo::InternalSwap(GeneratedCodeInfo* PROTOBUF_RESTRICT other) } ::google::protobuf::Metadata GeneratedCodeInfo::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, - file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[31]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto_once, + file_level_metadata_google_2fprotobuf_2fdescriptor_2eproto[31]); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index ea38e1f3d0..4e7aec590f 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -1,6 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/descriptor.proto -// Protobuf C++ Version: 4.24.0-main +// Protobuf C++ Version: 4.26.0-dev #ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto_2epb_2eh #define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fdescriptor_2eproto_2epb_2eh @@ -11,17 +11,11 @@ #include #include "google/protobuf/port_def.inc" -#if PROTOBUF_VERSION < 4024000 -#error "This file was generated by a newer version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please update" -#error "your headers." -#endif // PROTOBUF_VERSION - -#if 4024000 < PROTOBUF_MIN_PROTOC_VERSION -#error "This file was generated by an older version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please" -#error "regenerate this file with a newer version of protoc." -#endif // PROTOBUF_MIN_PROTOC_VERSION +#if PROTOBUF_VERSION != 4026000 +#error "Protobuf C++ gencode is built with an incompatible version of" +#error "Protobuf C++ headers/runtime. See" +#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp" +#endif #include "google/protobuf/port_undef.inc" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/arena.h" @@ -548,15 +542,15 @@ inline bool FeatureSet_RepeatedFieldEncoding_Parse(absl::string_view name, Featu } enum FeatureSet_Utf8Validation : int { FeatureSet_Utf8Validation_UTF8_VALIDATION_UNKNOWN = 0, - FeatureSet_Utf8Validation_NONE = 1, FeatureSet_Utf8Validation_VERIFY = 2, + FeatureSet_Utf8Validation_NONE = 3, }; PROTOBUF_EXPORT bool FeatureSet_Utf8Validation_IsValid(int value); PROTOBUF_EXPORT extern const uint32_t FeatureSet_Utf8Validation_internal_data_[]; constexpr FeatureSet_Utf8Validation FeatureSet_Utf8Validation_Utf8Validation_MIN = static_cast(0); -constexpr FeatureSet_Utf8Validation FeatureSet_Utf8Validation_Utf8Validation_MAX = static_cast(2); -constexpr int FeatureSet_Utf8Validation_Utf8Validation_ARRAYSIZE = 2 + 1; +constexpr FeatureSet_Utf8Validation FeatureSet_Utf8Validation_Utf8Validation_MAX = static_cast(3); +constexpr int FeatureSet_Utf8Validation_Utf8Validation_ARRAYSIZE = 3 + 1; PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FeatureSet_Utf8Validation_descriptor(); template @@ -569,7 +563,7 @@ const std::string& FeatureSet_Utf8Validation_Name(T value) { template <> inline const std::string& FeatureSet_Utf8Validation_Name(FeatureSet_Utf8Validation value) { return ::google::protobuf::internal::NameOfDenseEnum( + 0, 3>( static_cast(value)); } inline bool FeatureSet_Utf8Validation_Parse(absl::string_view name, FeatureSet_Utf8Validation* value) { @@ -676,13 +670,13 @@ enum Edition : int { EDITION_99997_TEST_ONLY = 99997, EDITION_99998_TEST_ONLY = 99998, EDITION_99999_TEST_ONLY = 99999, + EDITION_MAX = 2147483647, }; PROTOBUF_EXPORT bool Edition_IsValid(int value); PROTOBUF_EXPORT extern const uint32_t Edition_internal_data_[]; constexpr Edition Edition_MIN = static_cast(0); -constexpr Edition Edition_MAX = static_cast(99999); -constexpr int Edition_ARRAYSIZE = 99999 + 1; +constexpr Edition Edition_MAX = static_cast(2147483647); PROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* Edition_descriptor(); template @@ -702,21 +696,18 @@ inline bool Edition_Parse(absl::string_view name, Edition* value) { // ------------------------------------------------------------------- -class PROTOBUF_EXPORT UninterpretedOption_NamePart final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption.NamePart) */ { +class PROTOBUF_EXPORT UninterpretedOption_NamePart final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption.NamePart) */ { public: inline UninterpretedOption_NamePart() : UninterpretedOption_NamePart(nullptr) {} ~UninterpretedOption_NamePart() override; - template - explicit PROTOBUF_CONSTEXPR UninterpretedOption_NamePart(::google::protobuf::internal::ConstantInitialized); - - inline UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from) - : UninterpretedOption_NamePart(nullptr, from) {} - UninterpretedOption_NamePart(UninterpretedOption_NamePart&& from) noexcept - : UninterpretedOption_NamePart() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR UninterpretedOption_NamePart( + ::google::protobuf::internal::ConstantInitialized); + inline UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from) : UninterpretedOption_NamePart(nullptr, from) {} + inline UninterpretedOption_NamePart(UninterpretedOption_NamePart&& from) noexcept + : UninterpretedOption_NamePart(nullptr, std::move(from)) {} inline UninterpretedOption_NamePart& operator=(const UninterpretedOption_NamePart& from) { CopyFrom(from); return *this; @@ -724,9 +715,9 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart final : inline UninterpretedOption_NamePart& operator=(UninterpretedOption_NamePart&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -758,22 +749,17 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart final : } static inline const UninterpretedOption_NamePart* internal_default_instance() { return reinterpret_cast( - &_UninterpretedOption_NamePart_default_instance_); - } - static constexpr int kIndexInFileMessages = - 23; - - friend void swap(UninterpretedOption_NamePart& a, UninterpretedOption_NamePart& b) { - a.Swap(&b); + &_UninterpretedOption_NamePart_default_instance_); } + static constexpr int kIndexInFileMessages = 23; + friend void swap(UninterpretedOption_NamePart& a, UninterpretedOption_NamePart& b) { a.Swap(&b); } inline void Swap(UninterpretedOption_NamePart* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -788,16 +774,18 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart final : // implements Message ---------------------------------------------- UninterpretedOption_NamePart* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const UninterpretedOption_NamePart& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const UninterpretedOption_NamePart& from) { - UninterpretedOption_NamePart::MergeImpl(*this, from); - } + void MergeFrom(const UninterpretedOption_NamePart& from) { UninterpretedOption_NamePart::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -805,32 +793,33 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(UninterpretedOption_NamePart* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.UninterpretedOption.NamePart"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.UninterpretedOption.NamePart"; } + + protected: explicit UninterpretedOption_NamePart(::google::protobuf::Arena* arena); UninterpretedOption_NamePart(::google::protobuf::Arena* arena, const UninterpretedOption_NamePart& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + UninterpretedOption_NamePart(::google::protobuf::Arena* arena, UninterpretedOption_NamePart&& from) noexcept + : UninterpretedOption_NamePart(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kNamePartFieldNumber = 1, kIsExtensionFieldNumber = 2, @@ -866,7 +855,6 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart final : // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 1, 2, 0, @@ -878,14 +866,13 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::internal::ArenaStringPtr name_part_; @@ -894,23 +881,21 @@ class PROTOBUF_EXPORT UninterpretedOption_NamePart final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT SourceCodeInfo_Location final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo.Location) */ { +class PROTOBUF_EXPORT SourceCodeInfo_Location final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo.Location) */ { public: inline SourceCodeInfo_Location() : SourceCodeInfo_Location(nullptr) {} ~SourceCodeInfo_Location() override; - template - explicit PROTOBUF_CONSTEXPR SourceCodeInfo_Location(::google::protobuf::internal::ConstantInitialized); - - inline SourceCodeInfo_Location(const SourceCodeInfo_Location& from) - : SourceCodeInfo_Location(nullptr, from) {} - SourceCodeInfo_Location(SourceCodeInfo_Location&& from) noexcept - : SourceCodeInfo_Location() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR SourceCodeInfo_Location( + ::google::protobuf::internal::ConstantInitialized); + inline SourceCodeInfo_Location(const SourceCodeInfo_Location& from) : SourceCodeInfo_Location(nullptr, from) {} + inline SourceCodeInfo_Location(SourceCodeInfo_Location&& from) noexcept + : SourceCodeInfo_Location(nullptr, std::move(from)) {} inline SourceCodeInfo_Location& operator=(const SourceCodeInfo_Location& from) { CopyFrom(from); return *this; @@ -918,9 +903,9 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location final : inline SourceCodeInfo_Location& operator=(SourceCodeInfo_Location&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -952,22 +937,17 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location final : } static inline const SourceCodeInfo_Location* internal_default_instance() { return reinterpret_cast( - &_SourceCodeInfo_Location_default_instance_); - } - static constexpr int kIndexInFileMessages = - 28; - - friend void swap(SourceCodeInfo_Location& a, SourceCodeInfo_Location& b) { - a.Swap(&b); + &_SourceCodeInfo_Location_default_instance_); } + static constexpr int kIndexInFileMessages = 28; + friend void swap(SourceCodeInfo_Location& a, SourceCodeInfo_Location& b) { a.Swap(&b); } inline void Swap(SourceCodeInfo_Location* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -982,16 +962,18 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location final : // implements Message ---------------------------------------------- SourceCodeInfo_Location* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const SourceCodeInfo_Location& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const SourceCodeInfo_Location& from) { - SourceCodeInfo_Location::MergeImpl(*this, from); - } + void MergeFrom(const SourceCodeInfo_Location& from) { SourceCodeInfo_Location::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -999,32 +981,33 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(SourceCodeInfo_Location* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.SourceCodeInfo.Location"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.SourceCodeInfo.Location"; } + + protected: explicit SourceCodeInfo_Location(::google::protobuf::Arena* arena); SourceCodeInfo_Location(::google::protobuf::Arena* arena, const SourceCodeInfo_Location& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + SourceCodeInfo_Location(::google::protobuf::Arena* arena, SourceCodeInfo_Location&& from) noexcept + : SourceCodeInfo_Location(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kPathFieldNumber = 1, kSpanFieldNumber = 2, @@ -1133,7 +1116,6 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location final : // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 3, 5, 0, @@ -1145,14 +1127,13 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedField<::int32_t> path_; @@ -1166,23 +1147,21 @@ class PROTOBUF_EXPORT SourceCodeInfo_Location final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo.Annotation) */ { +class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo.Annotation) */ { public: inline GeneratedCodeInfo_Annotation() : GeneratedCodeInfo_Annotation(nullptr) {} ~GeneratedCodeInfo_Annotation() override; - template - explicit PROTOBUF_CONSTEXPR GeneratedCodeInfo_Annotation(::google::protobuf::internal::ConstantInitialized); - - inline GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from) - : GeneratedCodeInfo_Annotation(nullptr, from) {} - GeneratedCodeInfo_Annotation(GeneratedCodeInfo_Annotation&& from) noexcept - : GeneratedCodeInfo_Annotation() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR GeneratedCodeInfo_Annotation( + ::google::protobuf::internal::ConstantInitialized); + inline GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from) : GeneratedCodeInfo_Annotation(nullptr, from) {} + inline GeneratedCodeInfo_Annotation(GeneratedCodeInfo_Annotation&& from) noexcept + : GeneratedCodeInfo_Annotation(nullptr, std::move(from)) {} inline GeneratedCodeInfo_Annotation& operator=(const GeneratedCodeInfo_Annotation& from) { CopyFrom(from); return *this; @@ -1190,9 +1169,9 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final : inline GeneratedCodeInfo_Annotation& operator=(GeneratedCodeInfo_Annotation&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -1224,22 +1203,17 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final : } static inline const GeneratedCodeInfo_Annotation* internal_default_instance() { return reinterpret_cast( - &_GeneratedCodeInfo_Annotation_default_instance_); - } - static constexpr int kIndexInFileMessages = - 30; - - friend void swap(GeneratedCodeInfo_Annotation& a, GeneratedCodeInfo_Annotation& b) { - a.Swap(&b); + &_GeneratedCodeInfo_Annotation_default_instance_); } + static constexpr int kIndexInFileMessages = 30; + friend void swap(GeneratedCodeInfo_Annotation& a, GeneratedCodeInfo_Annotation& b) { a.Swap(&b); } inline void Swap(GeneratedCodeInfo_Annotation* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -1254,16 +1228,18 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final : // implements Message ---------------------------------------------- GeneratedCodeInfo_Annotation* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const GeneratedCodeInfo_Annotation& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const GeneratedCodeInfo_Annotation& from) { - GeneratedCodeInfo_Annotation::MergeImpl(*this, from); - } + void MergeFrom(const GeneratedCodeInfo_Annotation& from) { GeneratedCodeInfo_Annotation::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -1271,30 +1247,31 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(GeneratedCodeInfo_Annotation* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.GeneratedCodeInfo.Annotation"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.GeneratedCodeInfo.Annotation"; } + + protected: explicit GeneratedCodeInfo_Annotation(::google::protobuf::Arena* arena); GeneratedCodeInfo_Annotation(::google::protobuf::Arena* arena, const GeneratedCodeInfo_Annotation& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + GeneratedCodeInfo_Annotation(::google::protobuf::Arena* arena, GeneratedCodeInfo_Annotation&& from) noexcept + : GeneratedCodeInfo_Annotation(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- - using Semantic = GeneratedCodeInfo_Annotation_Semantic; static constexpr Semantic NONE = GeneratedCodeInfo_Annotation_Semantic_NONE; static constexpr Semantic SET = GeneratedCodeInfo_Annotation_Semantic_SET; @@ -1317,7 +1294,6 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final : } // accessors ------------------------------------------------------- - enum : int { kPathFieldNumber = 1, kSourceFileFieldNumber = 2, @@ -1396,7 +1372,6 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final : // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo.Annotation) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 3, 5, 1, @@ -1408,14 +1383,13 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedField<::int32_t> path_; @@ -1428,23 +1402,21 @@ class PROTOBUF_EXPORT GeneratedCodeInfo_Annotation final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT FieldOptions_EditionDefault final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldOptions.EditionDefault) */ { +class PROTOBUF_EXPORT FieldOptions_EditionDefault final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.FieldOptions.EditionDefault) */ { public: inline FieldOptions_EditionDefault() : FieldOptions_EditionDefault(nullptr) {} ~FieldOptions_EditionDefault() override; - template - explicit PROTOBUF_CONSTEXPR FieldOptions_EditionDefault(::google::protobuf::internal::ConstantInitialized); - - inline FieldOptions_EditionDefault(const FieldOptions_EditionDefault& from) - : FieldOptions_EditionDefault(nullptr, from) {} - FieldOptions_EditionDefault(FieldOptions_EditionDefault&& from) noexcept - : FieldOptions_EditionDefault() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR FieldOptions_EditionDefault( + ::google::protobuf::internal::ConstantInitialized); + inline FieldOptions_EditionDefault(const FieldOptions_EditionDefault& from) : FieldOptions_EditionDefault(nullptr, from) {} + inline FieldOptions_EditionDefault(FieldOptions_EditionDefault&& from) noexcept + : FieldOptions_EditionDefault(nullptr, std::move(from)) {} inline FieldOptions_EditionDefault& operator=(const FieldOptions_EditionDefault& from) { CopyFrom(from); return *this; @@ -1452,9 +1424,9 @@ class PROTOBUF_EXPORT FieldOptions_EditionDefault final : inline FieldOptions_EditionDefault& operator=(FieldOptions_EditionDefault&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -1486,22 +1458,17 @@ class PROTOBUF_EXPORT FieldOptions_EditionDefault final : } static inline const FieldOptions_EditionDefault* internal_default_instance() { return reinterpret_cast( - &_FieldOptions_EditionDefault_default_instance_); - } - static constexpr int kIndexInFileMessages = - 16; - - friend void swap(FieldOptions_EditionDefault& a, FieldOptions_EditionDefault& b) { - a.Swap(&b); + &_FieldOptions_EditionDefault_default_instance_); } + static constexpr int kIndexInFileMessages = 16; + friend void swap(FieldOptions_EditionDefault& a, FieldOptions_EditionDefault& b) { a.Swap(&b); } inline void Swap(FieldOptions_EditionDefault* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -1516,16 +1483,18 @@ class PROTOBUF_EXPORT FieldOptions_EditionDefault final : // implements Message ---------------------------------------------- FieldOptions_EditionDefault* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const FieldOptions_EditionDefault& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const FieldOptions_EditionDefault& from) { - FieldOptions_EditionDefault::MergeImpl(*this, from); - } + void MergeFrom(const FieldOptions_EditionDefault& from) { FieldOptions_EditionDefault::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -1533,32 +1502,33 @@ class PROTOBUF_EXPORT FieldOptions_EditionDefault final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(FieldOptions_EditionDefault* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.FieldOptions.EditionDefault"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.FieldOptions.EditionDefault"; } + + protected: explicit FieldOptions_EditionDefault(::google::protobuf::Arena* arena); FieldOptions_EditionDefault(::google::protobuf::Arena* arena, const FieldOptions_EditionDefault& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + FieldOptions_EditionDefault(::google::protobuf::Arena* arena, FieldOptions_EditionDefault&& from) noexcept + : FieldOptions_EditionDefault(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kValueFieldNumber = 2, kEditionFieldNumber = 3, @@ -1594,7 +1564,6 @@ class PROTOBUF_EXPORT FieldOptions_EditionDefault final : // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions.EditionDefault) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 1, 2, 1, @@ -1606,14 +1575,13 @@ class PROTOBUF_EXPORT FieldOptions_EditionDefault final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::internal::ArenaStringPtr value_; @@ -1622,23 +1590,21 @@ class PROTOBUF_EXPORT FieldOptions_EditionDefault final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT FeatureSet final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FeatureSet) */ { +class PROTOBUF_EXPORT FeatureSet final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.FeatureSet) */ { public: inline FeatureSet() : FeatureSet(nullptr) {} ~FeatureSet() override; - template - explicit PROTOBUF_CONSTEXPR FeatureSet(::google::protobuf::internal::ConstantInitialized); - - inline FeatureSet(const FeatureSet& from) - : FeatureSet(nullptr, from) {} - FeatureSet(FeatureSet&& from) noexcept - : FeatureSet() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR FeatureSet( + ::google::protobuf::internal::ConstantInitialized); + inline FeatureSet(const FeatureSet& from) : FeatureSet(nullptr, from) {} + inline FeatureSet(FeatureSet&& from) noexcept + : FeatureSet(nullptr, std::move(from)) {} inline FeatureSet& operator=(const FeatureSet& from) { CopyFrom(from); return *this; @@ -1646,9 +1612,9 @@ class PROTOBUF_EXPORT FeatureSet final : inline FeatureSet& operator=(FeatureSet&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -1680,22 +1646,17 @@ class PROTOBUF_EXPORT FeatureSet final : } static inline const FeatureSet* internal_default_instance() { return reinterpret_cast( - &_FeatureSet_default_instance_); - } - static constexpr int kIndexInFileMessages = - 25; - - friend void swap(FeatureSet& a, FeatureSet& b) { - a.Swap(&b); + &_FeatureSet_default_instance_); } + static constexpr int kIndexInFileMessages = 25; + friend void swap(FeatureSet& a, FeatureSet& b) { a.Swap(&b); } inline void Swap(FeatureSet* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -1710,16 +1671,18 @@ class PROTOBUF_EXPORT FeatureSet final : // implements Message ---------------------------------------------- FeatureSet* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const FeatureSet& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const FeatureSet& from) { - FeatureSet::MergeImpl(*this, from); - } + void MergeFrom(const FeatureSet& from) { FeatureSet::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -1727,30 +1690,31 @@ class PROTOBUF_EXPORT FeatureSet final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(FeatureSet* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.FeatureSet"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.FeatureSet"; } + + protected: explicit FeatureSet(::google::protobuf::Arena* arena); FeatureSet(::google::protobuf::Arena* arena, const FeatureSet& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + FeatureSet(::google::protobuf::Arena* arena, FeatureSet&& from) noexcept + : FeatureSet(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- - using FieldPresence = FeatureSet_FieldPresence; static constexpr FieldPresence FIELD_PRESENCE_UNKNOWN = FeatureSet_FieldPresence_FIELD_PRESENCE_UNKNOWN; static constexpr FieldPresence EXPLICIT = FeatureSet_FieldPresence_EXPLICIT; @@ -1772,7 +1736,6 @@ class PROTOBUF_EXPORT FeatureSet final : static inline bool FieldPresence_Parse(absl::string_view name, FieldPresence* value) { return FeatureSet_FieldPresence_Parse(name, value); } - using EnumType = FeatureSet_EnumType; static constexpr EnumType ENUM_TYPE_UNKNOWN = FeatureSet_EnumType_ENUM_TYPE_UNKNOWN; static constexpr EnumType OPEN = FeatureSet_EnumType_OPEN; @@ -1793,7 +1756,6 @@ class PROTOBUF_EXPORT FeatureSet final : static inline bool EnumType_Parse(absl::string_view name, EnumType* value) { return FeatureSet_EnumType_Parse(name, value); } - using RepeatedFieldEncoding = FeatureSet_RepeatedFieldEncoding; static constexpr RepeatedFieldEncoding REPEATED_FIELD_ENCODING_UNKNOWN = FeatureSet_RepeatedFieldEncoding_REPEATED_FIELD_ENCODING_UNKNOWN; static constexpr RepeatedFieldEncoding PACKED = FeatureSet_RepeatedFieldEncoding_PACKED; @@ -1814,11 +1776,10 @@ class PROTOBUF_EXPORT FeatureSet final : static inline bool RepeatedFieldEncoding_Parse(absl::string_view name, RepeatedFieldEncoding* value) { return FeatureSet_RepeatedFieldEncoding_Parse(name, value); } - using Utf8Validation = FeatureSet_Utf8Validation; static constexpr Utf8Validation UTF8_VALIDATION_UNKNOWN = FeatureSet_Utf8Validation_UTF8_VALIDATION_UNKNOWN; - static constexpr Utf8Validation NONE = FeatureSet_Utf8Validation_NONE; static constexpr Utf8Validation VERIFY = FeatureSet_Utf8Validation_VERIFY; + static constexpr Utf8Validation NONE = FeatureSet_Utf8Validation_NONE; static inline bool Utf8Validation_IsValid(int value) { return FeatureSet_Utf8Validation_IsValid(value); } @@ -1835,7 +1796,6 @@ class PROTOBUF_EXPORT FeatureSet final : static inline bool Utf8Validation_Parse(absl::string_view name, Utf8Validation* value) { return FeatureSet_Utf8Validation_Parse(name, value); } - using MessageEncoding = FeatureSet_MessageEncoding; static constexpr MessageEncoding MESSAGE_ENCODING_UNKNOWN = FeatureSet_MessageEncoding_MESSAGE_ENCODING_UNKNOWN; static constexpr MessageEncoding LENGTH_PREFIXED = FeatureSet_MessageEncoding_LENGTH_PREFIXED; @@ -1856,7 +1816,6 @@ class PROTOBUF_EXPORT FeatureSet final : static inline bool MessageEncoding_Parse(absl::string_view name, MessageEncoding* value) { return FeatureSet_MessageEncoding_Parse(name, value); } - using JsonFormat = FeatureSet_JsonFormat; static constexpr JsonFormat JSON_FORMAT_UNKNOWN = FeatureSet_JsonFormat_JSON_FORMAT_UNKNOWN; static constexpr JsonFormat ALLOW = FeatureSet_JsonFormat_ALLOW; @@ -1879,7 +1838,6 @@ class PROTOBUF_EXPORT FeatureSet final : } // accessors ------------------------------------------------------- - enum : int { kFieldPresenceFieldNumber = 1, kEnumTypeFieldNumber = 2, @@ -2134,7 +2092,6 @@ class PROTOBUF_EXPORT FeatureSet final : // @@protoc_insertion_point(class_scope:google.protobuf.FeatureSet) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 3, 6, 6, @@ -2146,16 +2103,14 @@ class PROTOBUF_EXPORT FeatureSet final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; int field_presence_; @@ -2168,23 +2123,21 @@ class PROTOBUF_EXPORT FeatureSet final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT ExtensionRangeOptions_Declaration final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ExtensionRangeOptions.Declaration) */ { +class PROTOBUF_EXPORT ExtensionRangeOptions_Declaration final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.ExtensionRangeOptions.Declaration) */ { public: inline ExtensionRangeOptions_Declaration() : ExtensionRangeOptions_Declaration(nullptr) {} ~ExtensionRangeOptions_Declaration() override; - template - explicit PROTOBUF_CONSTEXPR ExtensionRangeOptions_Declaration(::google::protobuf::internal::ConstantInitialized); - - inline ExtensionRangeOptions_Declaration(const ExtensionRangeOptions_Declaration& from) - : ExtensionRangeOptions_Declaration(nullptr, from) {} - ExtensionRangeOptions_Declaration(ExtensionRangeOptions_Declaration&& from) noexcept - : ExtensionRangeOptions_Declaration() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR ExtensionRangeOptions_Declaration( + ::google::protobuf::internal::ConstantInitialized); + inline ExtensionRangeOptions_Declaration(const ExtensionRangeOptions_Declaration& from) : ExtensionRangeOptions_Declaration(nullptr, from) {} + inline ExtensionRangeOptions_Declaration(ExtensionRangeOptions_Declaration&& from) noexcept + : ExtensionRangeOptions_Declaration(nullptr, std::move(from)) {} inline ExtensionRangeOptions_Declaration& operator=(const ExtensionRangeOptions_Declaration& from) { CopyFrom(from); return *this; @@ -2192,9 +2145,9 @@ class PROTOBUF_EXPORT ExtensionRangeOptions_Declaration final : inline ExtensionRangeOptions_Declaration& operator=(ExtensionRangeOptions_Declaration&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -2226,22 +2179,17 @@ class PROTOBUF_EXPORT ExtensionRangeOptions_Declaration final : } static inline const ExtensionRangeOptions_Declaration* internal_default_instance() { return reinterpret_cast( - &_ExtensionRangeOptions_Declaration_default_instance_); - } - static constexpr int kIndexInFileMessages = - 5; - - friend void swap(ExtensionRangeOptions_Declaration& a, ExtensionRangeOptions_Declaration& b) { - a.Swap(&b); + &_ExtensionRangeOptions_Declaration_default_instance_); } + static constexpr int kIndexInFileMessages = 5; + friend void swap(ExtensionRangeOptions_Declaration& a, ExtensionRangeOptions_Declaration& b) { a.Swap(&b); } inline void Swap(ExtensionRangeOptions_Declaration* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -2256,16 +2204,18 @@ class PROTOBUF_EXPORT ExtensionRangeOptions_Declaration final : // implements Message ---------------------------------------------- ExtensionRangeOptions_Declaration* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const ExtensionRangeOptions_Declaration& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const ExtensionRangeOptions_Declaration& from) { - ExtensionRangeOptions_Declaration::MergeImpl(*this, from); - } + void MergeFrom(const ExtensionRangeOptions_Declaration& from) { ExtensionRangeOptions_Declaration::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -2273,32 +2223,33 @@ class PROTOBUF_EXPORT ExtensionRangeOptions_Declaration final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(ExtensionRangeOptions_Declaration* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.ExtensionRangeOptions.Declaration"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.ExtensionRangeOptions.Declaration"; } + + protected: explicit ExtensionRangeOptions_Declaration(::google::protobuf::Arena* arena); ExtensionRangeOptions_Declaration(::google::protobuf::Arena* arena, const ExtensionRangeOptions_Declaration& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + ExtensionRangeOptions_Declaration(::google::protobuf::Arena* arena, ExtensionRangeOptions_Declaration&& from) noexcept + : ExtensionRangeOptions_Declaration(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kFullNameFieldNumber = 2, kTypeFieldNumber = 3, @@ -2376,7 +2327,6 @@ class PROTOBUF_EXPORT ExtensionRangeOptions_Declaration final : // @@protoc_insertion_point(class_scope:google.protobuf.ExtensionRangeOptions.Declaration) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 3, 5, 0, @@ -2388,14 +2338,13 @@ class PROTOBUF_EXPORT ExtensionRangeOptions_Declaration final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::internal::ArenaStringPtr full_name_; @@ -2407,23 +2356,21 @@ class PROTOBUF_EXPORT ExtensionRangeOptions_Declaration final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto.EnumReservedRange) */ { +class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto.EnumReservedRange) */ { public: inline EnumDescriptorProto_EnumReservedRange() : EnumDescriptorProto_EnumReservedRange(nullptr) {} ~EnumDescriptorProto_EnumReservedRange() override; - template - explicit PROTOBUF_CONSTEXPR EnumDescriptorProto_EnumReservedRange(::google::protobuf::internal::ConstantInitialized); - - inline EnumDescriptorProto_EnumReservedRange(const EnumDescriptorProto_EnumReservedRange& from) - : EnumDescriptorProto_EnumReservedRange(nullptr, from) {} - EnumDescriptorProto_EnumReservedRange(EnumDescriptorProto_EnumReservedRange&& from) noexcept - : EnumDescriptorProto_EnumReservedRange() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR EnumDescriptorProto_EnumReservedRange( + ::google::protobuf::internal::ConstantInitialized); + inline EnumDescriptorProto_EnumReservedRange(const EnumDescriptorProto_EnumReservedRange& from) : EnumDescriptorProto_EnumReservedRange(nullptr, from) {} + inline EnumDescriptorProto_EnumReservedRange(EnumDescriptorProto_EnumReservedRange&& from) noexcept + : EnumDescriptorProto_EnumReservedRange(nullptr, std::move(from)) {} inline EnumDescriptorProto_EnumReservedRange& operator=(const EnumDescriptorProto_EnumReservedRange& from) { CopyFrom(from); return *this; @@ -2431,9 +2378,9 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange final : inline EnumDescriptorProto_EnumReservedRange& operator=(EnumDescriptorProto_EnumReservedRange&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -2465,22 +2412,17 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange final : } static inline const EnumDescriptorProto_EnumReservedRange* internal_default_instance() { return reinterpret_cast( - &_EnumDescriptorProto_EnumReservedRange_default_instance_); - } - static constexpr int kIndexInFileMessages = - 9; - - friend void swap(EnumDescriptorProto_EnumReservedRange& a, EnumDescriptorProto_EnumReservedRange& b) { - a.Swap(&b); + &_EnumDescriptorProto_EnumReservedRange_default_instance_); } + static constexpr int kIndexInFileMessages = 9; + friend void swap(EnumDescriptorProto_EnumReservedRange& a, EnumDescriptorProto_EnumReservedRange& b) { a.Swap(&b); } inline void Swap(EnumDescriptorProto_EnumReservedRange* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -2495,16 +2437,18 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange final : // implements Message ---------------------------------------------- EnumDescriptorProto_EnumReservedRange* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const EnumDescriptorProto_EnumReservedRange& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const EnumDescriptorProto_EnumReservedRange& from) { - EnumDescriptorProto_EnumReservedRange::MergeImpl(*this, from); - } + void MergeFrom(const EnumDescriptorProto_EnumReservedRange& from) { EnumDescriptorProto_EnumReservedRange::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -2512,32 +2456,33 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(EnumDescriptorProto_EnumReservedRange* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.EnumDescriptorProto.EnumReservedRange"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.EnumDescriptorProto.EnumReservedRange"; } + + protected: explicit EnumDescriptorProto_EnumReservedRange(::google::protobuf::Arena* arena); EnumDescriptorProto_EnumReservedRange(::google::protobuf::Arena* arena, const EnumDescriptorProto_EnumReservedRange& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + EnumDescriptorProto_EnumReservedRange(::google::protobuf::Arena* arena, EnumDescriptorProto_EnumReservedRange&& from) noexcept + : EnumDescriptorProto_EnumReservedRange(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kStartFieldNumber = 1, kEndFieldNumber = 2, @@ -2567,7 +2512,6 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange final : // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto.EnumReservedRange) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 1, 2, 0, @@ -2579,14 +2523,13 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::int32_t start_; @@ -2595,23 +2538,21 @@ class PROTOBUF_EXPORT EnumDescriptorProto_EnumReservedRange final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT DescriptorProto_ReservedRange final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ReservedRange) */ { +class PROTOBUF_EXPORT DescriptorProto_ReservedRange final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ReservedRange) */ { public: inline DescriptorProto_ReservedRange() : DescriptorProto_ReservedRange(nullptr) {} ~DescriptorProto_ReservedRange() override; - template - explicit PROTOBUF_CONSTEXPR DescriptorProto_ReservedRange(::google::protobuf::internal::ConstantInitialized); - - inline DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from) - : DescriptorProto_ReservedRange(nullptr, from) {} - DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&& from) noexcept - : DescriptorProto_ReservedRange() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR DescriptorProto_ReservedRange( + ::google::protobuf::internal::ConstantInitialized); + inline DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from) : DescriptorProto_ReservedRange(nullptr, from) {} + inline DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&& from) noexcept + : DescriptorProto_ReservedRange(nullptr, std::move(from)) {} inline DescriptorProto_ReservedRange& operator=(const DescriptorProto_ReservedRange& from) { CopyFrom(from); return *this; @@ -2619,9 +2560,9 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange final : inline DescriptorProto_ReservedRange& operator=(DescriptorProto_ReservedRange&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -2653,22 +2594,17 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange final : } static inline const DescriptorProto_ReservedRange* internal_default_instance() { return reinterpret_cast( - &_DescriptorProto_ReservedRange_default_instance_); - } - static constexpr int kIndexInFileMessages = - 3; - - friend void swap(DescriptorProto_ReservedRange& a, DescriptorProto_ReservedRange& b) { - a.Swap(&b); + &_DescriptorProto_ReservedRange_default_instance_); } + static constexpr int kIndexInFileMessages = 3; + friend void swap(DescriptorProto_ReservedRange& a, DescriptorProto_ReservedRange& b) { a.Swap(&b); } inline void Swap(DescriptorProto_ReservedRange* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -2683,16 +2619,18 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange final : // implements Message ---------------------------------------------- DescriptorProto_ReservedRange* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const DescriptorProto_ReservedRange& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const DescriptorProto_ReservedRange& from) { - DescriptorProto_ReservedRange::MergeImpl(*this, from); - } + void MergeFrom(const DescriptorProto_ReservedRange& from) { DescriptorProto_ReservedRange::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -2700,32 +2638,33 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(DescriptorProto_ReservedRange* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.DescriptorProto.ReservedRange"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.DescriptorProto.ReservedRange"; } + + protected: explicit DescriptorProto_ReservedRange(::google::protobuf::Arena* arena); DescriptorProto_ReservedRange(::google::protobuf::Arena* arena, const DescriptorProto_ReservedRange& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + DescriptorProto_ReservedRange(::google::protobuf::Arena* arena, DescriptorProto_ReservedRange&& from) noexcept + : DescriptorProto_ReservedRange(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kStartFieldNumber = 1, kEndFieldNumber = 2, @@ -2755,7 +2694,6 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange final : // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ReservedRange) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 1, 2, 0, @@ -2767,14 +2705,13 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::int32_t start_; @@ -2783,23 +2720,21 @@ class PROTOBUF_EXPORT DescriptorProto_ReservedRange final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT UninterpretedOption final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption) */ { +class PROTOBUF_EXPORT UninterpretedOption final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.UninterpretedOption) */ { public: inline UninterpretedOption() : UninterpretedOption(nullptr) {} ~UninterpretedOption() override; - template - explicit PROTOBUF_CONSTEXPR UninterpretedOption(::google::protobuf::internal::ConstantInitialized); - - inline UninterpretedOption(const UninterpretedOption& from) - : UninterpretedOption(nullptr, from) {} - UninterpretedOption(UninterpretedOption&& from) noexcept - : UninterpretedOption() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR UninterpretedOption( + ::google::protobuf::internal::ConstantInitialized); + inline UninterpretedOption(const UninterpretedOption& from) : UninterpretedOption(nullptr, from) {} + inline UninterpretedOption(UninterpretedOption&& from) noexcept + : UninterpretedOption(nullptr, std::move(from)) {} inline UninterpretedOption& operator=(const UninterpretedOption& from) { CopyFrom(from); return *this; @@ -2807,9 +2742,9 @@ class PROTOBUF_EXPORT UninterpretedOption final : inline UninterpretedOption& operator=(UninterpretedOption&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -2841,22 +2776,17 @@ class PROTOBUF_EXPORT UninterpretedOption final : } static inline const UninterpretedOption* internal_default_instance() { return reinterpret_cast( - &_UninterpretedOption_default_instance_); - } - static constexpr int kIndexInFileMessages = - 24; - - friend void swap(UninterpretedOption& a, UninterpretedOption& b) { - a.Swap(&b); + &_UninterpretedOption_default_instance_); } + static constexpr int kIndexInFileMessages = 24; + friend void swap(UninterpretedOption& a, UninterpretedOption& b) { a.Swap(&b); } inline void Swap(UninterpretedOption* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -2871,16 +2801,18 @@ class PROTOBUF_EXPORT UninterpretedOption final : // implements Message ---------------------------------------------- UninterpretedOption* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const UninterpretedOption& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const UninterpretedOption& from) { - UninterpretedOption::MergeImpl(*this, from); - } + void MergeFrom(const UninterpretedOption& from) { UninterpretedOption::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -2888,34 +2820,34 @@ class PROTOBUF_EXPORT UninterpretedOption final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(UninterpretedOption* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.UninterpretedOption"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.UninterpretedOption"; } + + protected: explicit UninterpretedOption(::google::protobuf::Arena* arena); UninterpretedOption(::google::protobuf::Arena* arena, const UninterpretedOption& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + UninterpretedOption(::google::protobuf::Arena* arena, UninterpretedOption&& from) noexcept + : UninterpretedOption(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- - using NamePart = UninterpretedOption_NamePart; // accessors ------------------------------------------------------- - enum : int { kNameFieldNumber = 2, kIdentifierValueFieldNumber = 3, @@ -2933,16 +2865,15 @@ class PROTOBUF_EXPORT UninterpretedOption final : public: void clear_name() ; ::google::protobuf::UninterpretedOption_NamePart* mutable_name(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >* - mutable_name(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption_NamePart>* mutable_name(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption_NamePart>& _internal_name() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption_NamePart>* _internal_mutable_name(); public: const ::google::protobuf::UninterpretedOption_NamePart& name(int index) const; ::google::protobuf::UninterpretedOption_NamePart* add_name(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >& - name() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption_NamePart>& name() const; // optional string identifier_value = 3; bool has_identifier_value() const; void clear_identifier_value() ; @@ -3030,7 +2961,6 @@ class PROTOBUF_EXPORT UninterpretedOption final : // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 3, 7, 1, @@ -3042,14 +2972,13 @@ class PROTOBUF_EXPORT UninterpretedOption final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart > name_; @@ -3063,23 +2992,21 @@ class PROTOBUF_EXPORT UninterpretedOption final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT SourceCodeInfo final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo) */ { +class PROTOBUF_EXPORT SourceCodeInfo final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.SourceCodeInfo) */ { public: inline SourceCodeInfo() : SourceCodeInfo(nullptr) {} ~SourceCodeInfo() override; - template - explicit PROTOBUF_CONSTEXPR SourceCodeInfo(::google::protobuf::internal::ConstantInitialized); - - inline SourceCodeInfo(const SourceCodeInfo& from) - : SourceCodeInfo(nullptr, from) {} - SourceCodeInfo(SourceCodeInfo&& from) noexcept - : SourceCodeInfo() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR SourceCodeInfo( + ::google::protobuf::internal::ConstantInitialized); + inline SourceCodeInfo(const SourceCodeInfo& from) : SourceCodeInfo(nullptr, from) {} + inline SourceCodeInfo(SourceCodeInfo&& from) noexcept + : SourceCodeInfo(nullptr, std::move(from)) {} inline SourceCodeInfo& operator=(const SourceCodeInfo& from) { CopyFrom(from); return *this; @@ -3087,9 +3014,9 @@ class PROTOBUF_EXPORT SourceCodeInfo final : inline SourceCodeInfo& operator=(SourceCodeInfo&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -3121,22 +3048,17 @@ class PROTOBUF_EXPORT SourceCodeInfo final : } static inline const SourceCodeInfo* internal_default_instance() { return reinterpret_cast( - &_SourceCodeInfo_default_instance_); - } - static constexpr int kIndexInFileMessages = - 29; - - friend void swap(SourceCodeInfo& a, SourceCodeInfo& b) { - a.Swap(&b); + &_SourceCodeInfo_default_instance_); } + static constexpr int kIndexInFileMessages = 29; + friend void swap(SourceCodeInfo& a, SourceCodeInfo& b) { a.Swap(&b); } inline void Swap(SourceCodeInfo* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -3151,16 +3073,18 @@ class PROTOBUF_EXPORT SourceCodeInfo final : // implements Message ---------------------------------------------- SourceCodeInfo* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const SourceCodeInfo& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const SourceCodeInfo& from) { - SourceCodeInfo::MergeImpl(*this, from); - } + void MergeFrom(const SourceCodeInfo& from) { SourceCodeInfo::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -3168,34 +3092,34 @@ class PROTOBUF_EXPORT SourceCodeInfo final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(SourceCodeInfo* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.SourceCodeInfo"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.SourceCodeInfo"; } + + protected: explicit SourceCodeInfo(::google::protobuf::Arena* arena); SourceCodeInfo(::google::protobuf::Arena* arena, const SourceCodeInfo& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + SourceCodeInfo(::google::protobuf::Arena* arena, SourceCodeInfo&& from) noexcept + : SourceCodeInfo(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- - using Location = SourceCodeInfo_Location; // accessors ------------------------------------------------------- - enum : int { kLocationFieldNumber = 1, }; @@ -3207,20 +3131,18 @@ class PROTOBUF_EXPORT SourceCodeInfo final : public: void clear_location() ; ::google::protobuf::SourceCodeInfo_Location* mutable_location(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >* - mutable_location(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::SourceCodeInfo_Location>* mutable_location(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::SourceCodeInfo_Location>& _internal_location() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::SourceCodeInfo_Location>* _internal_mutable_location(); public: const ::google::protobuf::SourceCodeInfo_Location& location(int index) const; ::google::protobuf::SourceCodeInfo_Location* add_location(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >& - location() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::SourceCodeInfo_Location>& location() const; // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 0, 1, 1, @@ -3232,37 +3154,34 @@ class PROTOBUF_EXPORT SourceCodeInfo final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location > location_; mutable ::google::protobuf::internal::CachedSize _cached_size_; PROTOBUF_TSAN_DECLARE_MEMBER }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT GeneratedCodeInfo final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo) */ { +class PROTOBUF_EXPORT GeneratedCodeInfo final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.GeneratedCodeInfo) */ { public: inline GeneratedCodeInfo() : GeneratedCodeInfo(nullptr) {} ~GeneratedCodeInfo() override; - template - explicit PROTOBUF_CONSTEXPR GeneratedCodeInfo(::google::protobuf::internal::ConstantInitialized); - - inline GeneratedCodeInfo(const GeneratedCodeInfo& from) - : GeneratedCodeInfo(nullptr, from) {} - GeneratedCodeInfo(GeneratedCodeInfo&& from) noexcept - : GeneratedCodeInfo() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR GeneratedCodeInfo( + ::google::protobuf::internal::ConstantInitialized); + inline GeneratedCodeInfo(const GeneratedCodeInfo& from) : GeneratedCodeInfo(nullptr, from) {} + inline GeneratedCodeInfo(GeneratedCodeInfo&& from) noexcept + : GeneratedCodeInfo(nullptr, std::move(from)) {} inline GeneratedCodeInfo& operator=(const GeneratedCodeInfo& from) { CopyFrom(from); return *this; @@ -3270,9 +3189,9 @@ class PROTOBUF_EXPORT GeneratedCodeInfo final : inline GeneratedCodeInfo& operator=(GeneratedCodeInfo&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -3304,22 +3223,17 @@ class PROTOBUF_EXPORT GeneratedCodeInfo final : } static inline const GeneratedCodeInfo* internal_default_instance() { return reinterpret_cast( - &_GeneratedCodeInfo_default_instance_); - } - static constexpr int kIndexInFileMessages = - 31; - - friend void swap(GeneratedCodeInfo& a, GeneratedCodeInfo& b) { - a.Swap(&b); + &_GeneratedCodeInfo_default_instance_); } + static constexpr int kIndexInFileMessages = 31; + friend void swap(GeneratedCodeInfo& a, GeneratedCodeInfo& b) { a.Swap(&b); } inline void Swap(GeneratedCodeInfo* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -3334,16 +3248,18 @@ class PROTOBUF_EXPORT GeneratedCodeInfo final : // implements Message ---------------------------------------------- GeneratedCodeInfo* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const GeneratedCodeInfo& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const GeneratedCodeInfo& from) { - GeneratedCodeInfo::MergeImpl(*this, from); - } + void MergeFrom(const GeneratedCodeInfo& from) { GeneratedCodeInfo::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -3351,34 +3267,34 @@ class PROTOBUF_EXPORT GeneratedCodeInfo final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(GeneratedCodeInfo* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.GeneratedCodeInfo"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.GeneratedCodeInfo"; } + + protected: explicit GeneratedCodeInfo(::google::protobuf::Arena* arena); GeneratedCodeInfo(::google::protobuf::Arena* arena, const GeneratedCodeInfo& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + GeneratedCodeInfo(::google::protobuf::Arena* arena, GeneratedCodeInfo&& from) noexcept + : GeneratedCodeInfo(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- - using Annotation = GeneratedCodeInfo_Annotation; // accessors ------------------------------------------------------- - enum : int { kAnnotationFieldNumber = 1, }; @@ -3390,20 +3306,18 @@ class PROTOBUF_EXPORT GeneratedCodeInfo final : public: void clear_annotation() ; ::google::protobuf::GeneratedCodeInfo_Annotation* mutable_annotation(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation >* - mutable_annotation(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::GeneratedCodeInfo_Annotation>* mutable_annotation(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::GeneratedCodeInfo_Annotation>& _internal_annotation() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::GeneratedCodeInfo_Annotation>* _internal_mutable_annotation(); public: const ::google::protobuf::GeneratedCodeInfo_Annotation& annotation(int index) const; ::google::protobuf::GeneratedCodeInfo_Annotation* add_annotation(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation >& - annotation() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::GeneratedCodeInfo_Annotation>& annotation() const; // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 0, 1, 1, @@ -3415,37 +3329,34 @@ class PROTOBUF_EXPORT GeneratedCodeInfo final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::RepeatedPtrField< ::google::protobuf::GeneratedCodeInfo_Annotation > annotation_; mutable ::google::protobuf::internal::CachedSize _cached_size_; PROTOBUF_TSAN_DECLARE_MEMBER }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT FeatureSetDefaults_FeatureSetEditionDefault final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault) */ { +class PROTOBUF_EXPORT FeatureSetDefaults_FeatureSetEditionDefault final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault) */ { public: inline FeatureSetDefaults_FeatureSetEditionDefault() : FeatureSetDefaults_FeatureSetEditionDefault(nullptr) {} ~FeatureSetDefaults_FeatureSetEditionDefault() override; - template - explicit PROTOBUF_CONSTEXPR FeatureSetDefaults_FeatureSetEditionDefault(::google::protobuf::internal::ConstantInitialized); - - inline FeatureSetDefaults_FeatureSetEditionDefault(const FeatureSetDefaults_FeatureSetEditionDefault& from) - : FeatureSetDefaults_FeatureSetEditionDefault(nullptr, from) {} - FeatureSetDefaults_FeatureSetEditionDefault(FeatureSetDefaults_FeatureSetEditionDefault&& from) noexcept - : FeatureSetDefaults_FeatureSetEditionDefault() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR FeatureSetDefaults_FeatureSetEditionDefault( + ::google::protobuf::internal::ConstantInitialized); + inline FeatureSetDefaults_FeatureSetEditionDefault(const FeatureSetDefaults_FeatureSetEditionDefault& from) : FeatureSetDefaults_FeatureSetEditionDefault(nullptr, from) {} + inline FeatureSetDefaults_FeatureSetEditionDefault(FeatureSetDefaults_FeatureSetEditionDefault&& from) noexcept + : FeatureSetDefaults_FeatureSetEditionDefault(nullptr, std::move(from)) {} inline FeatureSetDefaults_FeatureSetEditionDefault& operator=(const FeatureSetDefaults_FeatureSetEditionDefault& from) { CopyFrom(from); return *this; @@ -3453,9 +3364,9 @@ class PROTOBUF_EXPORT FeatureSetDefaults_FeatureSetEditionDefault final : inline FeatureSetDefaults_FeatureSetEditionDefault& operator=(FeatureSetDefaults_FeatureSetEditionDefault&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -3487,22 +3398,17 @@ class PROTOBUF_EXPORT FeatureSetDefaults_FeatureSetEditionDefault final : } static inline const FeatureSetDefaults_FeatureSetEditionDefault* internal_default_instance() { return reinterpret_cast( - &_FeatureSetDefaults_FeatureSetEditionDefault_default_instance_); - } - static constexpr int kIndexInFileMessages = - 26; - - friend void swap(FeatureSetDefaults_FeatureSetEditionDefault& a, FeatureSetDefaults_FeatureSetEditionDefault& b) { - a.Swap(&b); + &_FeatureSetDefaults_FeatureSetEditionDefault_default_instance_); } + static constexpr int kIndexInFileMessages = 26; + friend void swap(FeatureSetDefaults_FeatureSetEditionDefault& a, FeatureSetDefaults_FeatureSetEditionDefault& b) { a.Swap(&b); } inline void Swap(FeatureSetDefaults_FeatureSetEditionDefault* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -3517,16 +3423,18 @@ class PROTOBUF_EXPORT FeatureSetDefaults_FeatureSetEditionDefault final : // implements Message ---------------------------------------------- FeatureSetDefaults_FeatureSetEditionDefault* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const FeatureSetDefaults_FeatureSetEditionDefault& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const FeatureSetDefaults_FeatureSetEditionDefault& from) { - FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl(*this, from); - } + void MergeFrom(const FeatureSetDefaults_FeatureSetEditionDefault& from) { FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -3534,32 +3442,33 @@ class PROTOBUF_EXPORT FeatureSetDefaults_FeatureSetEditionDefault final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(FeatureSetDefaults_FeatureSetEditionDefault* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault"; } + + protected: explicit FeatureSetDefaults_FeatureSetEditionDefault(::google::protobuf::Arena* arena); FeatureSetDefaults_FeatureSetEditionDefault(::google::protobuf::Arena* arena, const FeatureSetDefaults_FeatureSetEditionDefault& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + FeatureSetDefaults_FeatureSetEditionDefault(::google::protobuf::Arena* arena, FeatureSetDefaults_FeatureSetEditionDefault&& from) noexcept + : FeatureSetDefaults_FeatureSetEditionDefault(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kFeaturesFieldNumber = 2, kEditionFieldNumber = 3, @@ -3593,7 +3502,6 @@ class PROTOBUF_EXPORT FeatureSetDefaults_FeatureSetEditionDefault final : // @@protoc_insertion_point(class_scope:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 1, 2, 2, @@ -3605,14 +3513,13 @@ class PROTOBUF_EXPORT FeatureSetDefaults_FeatureSetEditionDefault final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::FeatureSet* features_; @@ -3621,23 +3528,21 @@ class PROTOBUF_EXPORT FeatureSetDefaults_FeatureSetEditionDefault final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT ServiceOptions final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceOptions) */ { +class PROTOBUF_EXPORT ServiceOptions final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.ServiceOptions) */ { public: inline ServiceOptions() : ServiceOptions(nullptr) {} ~ServiceOptions() override; - template - explicit PROTOBUF_CONSTEXPR ServiceOptions(::google::protobuf::internal::ConstantInitialized); - - inline ServiceOptions(const ServiceOptions& from) - : ServiceOptions(nullptr, from) {} - ServiceOptions(ServiceOptions&& from) noexcept - : ServiceOptions() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR ServiceOptions( + ::google::protobuf::internal::ConstantInitialized); + inline ServiceOptions(const ServiceOptions& from) : ServiceOptions(nullptr, from) {} + inline ServiceOptions(ServiceOptions&& from) noexcept + : ServiceOptions(nullptr, std::move(from)) {} inline ServiceOptions& operator=(const ServiceOptions& from) { CopyFrom(from); return *this; @@ -3645,9 +3550,9 @@ class PROTOBUF_EXPORT ServiceOptions final : inline ServiceOptions& operator=(ServiceOptions&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -3679,22 +3584,17 @@ class PROTOBUF_EXPORT ServiceOptions final : } static inline const ServiceOptions* internal_default_instance() { return reinterpret_cast( - &_ServiceOptions_default_instance_); - } - static constexpr int kIndexInFileMessages = - 21; - - friend void swap(ServiceOptions& a, ServiceOptions& b) { - a.Swap(&b); + &_ServiceOptions_default_instance_); } + static constexpr int kIndexInFileMessages = 21; + friend void swap(ServiceOptions& a, ServiceOptions& b) { a.Swap(&b); } inline void Swap(ServiceOptions* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -3709,16 +3609,18 @@ class PROTOBUF_EXPORT ServiceOptions final : // implements Message ---------------------------------------------- ServiceOptions* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const ServiceOptions& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const ServiceOptions& from) { - ServiceOptions::MergeImpl(*this, from); - } + void MergeFrom(const ServiceOptions& from) { ServiceOptions::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -3726,32 +3628,33 @@ class PROTOBUF_EXPORT ServiceOptions final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(ServiceOptions* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.ServiceOptions"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.ServiceOptions"; } + + protected: explicit ServiceOptions(::google::protobuf::Arena* arena); ServiceOptions(::google::protobuf::Arena* arena, const ServiceOptions& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + ServiceOptions(::google::protobuf::Arena* arena, ServiceOptions&& from) noexcept + : ServiceOptions(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kUninterpretedOptionFieldNumber = 999, kFeaturesFieldNumber = 34, @@ -3765,16 +3668,15 @@ class PROTOBUF_EXPORT ServiceOptions final : public: void clear_uninterpreted_option() ; ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* - mutable_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option(); public: const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& - uninterpreted_option() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const; // optional .google.protobuf.FeatureSet features = 34; bool has_features() const; void clear_features() ; @@ -3981,7 +3883,6 @@ class PROTOBUF_EXPORT ServiceOptions final : // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 2, 3, 2, @@ -3993,16 +3894,14 @@ class PROTOBUF_EXPORT ServiceOptions final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; @@ -4012,23 +3911,21 @@ class PROTOBUF_EXPORT ServiceOptions final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT OneofOptions final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofOptions) */ { +class PROTOBUF_EXPORT OneofOptions final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.OneofOptions) */ { public: inline OneofOptions() : OneofOptions(nullptr) {} ~OneofOptions() override; - template - explicit PROTOBUF_CONSTEXPR OneofOptions(::google::protobuf::internal::ConstantInitialized); - - inline OneofOptions(const OneofOptions& from) - : OneofOptions(nullptr, from) {} - OneofOptions(OneofOptions&& from) noexcept - : OneofOptions() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR OneofOptions( + ::google::protobuf::internal::ConstantInitialized); + inline OneofOptions(const OneofOptions& from) : OneofOptions(nullptr, from) {} + inline OneofOptions(OneofOptions&& from) noexcept + : OneofOptions(nullptr, std::move(from)) {} inline OneofOptions& operator=(const OneofOptions& from) { CopyFrom(from); return *this; @@ -4036,9 +3933,9 @@ class PROTOBUF_EXPORT OneofOptions final : inline OneofOptions& operator=(OneofOptions&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -4070,22 +3967,17 @@ class PROTOBUF_EXPORT OneofOptions final : } static inline const OneofOptions* internal_default_instance() { return reinterpret_cast( - &_OneofOptions_default_instance_); - } - static constexpr int kIndexInFileMessages = - 18; - - friend void swap(OneofOptions& a, OneofOptions& b) { - a.Swap(&b); + &_OneofOptions_default_instance_); } + static constexpr int kIndexInFileMessages = 18; + friend void swap(OneofOptions& a, OneofOptions& b) { a.Swap(&b); } inline void Swap(OneofOptions* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -4100,16 +3992,18 @@ class PROTOBUF_EXPORT OneofOptions final : // implements Message ---------------------------------------------- OneofOptions* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const OneofOptions& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const OneofOptions& from) { - OneofOptions::MergeImpl(*this, from); - } + void MergeFrom(const OneofOptions& from) { OneofOptions::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -4117,32 +4011,33 @@ class PROTOBUF_EXPORT OneofOptions final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(OneofOptions* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.OneofOptions"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.OneofOptions"; } + + protected: explicit OneofOptions(::google::protobuf::Arena* arena); OneofOptions(::google::protobuf::Arena* arena, const OneofOptions& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + OneofOptions(::google::protobuf::Arena* arena, OneofOptions&& from) noexcept + : OneofOptions(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kUninterpretedOptionFieldNumber = 999, kFeaturesFieldNumber = 1, @@ -4155,16 +4050,15 @@ class PROTOBUF_EXPORT OneofOptions final : public: void clear_uninterpreted_option() ; ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* - mutable_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option(); public: const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& - uninterpreted_option() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const; // optional .google.protobuf.FeatureSet features = 1; bool has_features() const; void clear_features() ; @@ -4360,7 +4254,6 @@ class PROTOBUF_EXPORT OneofOptions final : // @@protoc_insertion_point(class_scope:google.protobuf.OneofOptions) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 2, 2, 2, @@ -4372,16 +4265,14 @@ class PROTOBUF_EXPORT OneofOptions final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; @@ -4390,23 +4281,21 @@ class PROTOBUF_EXPORT OneofOptions final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT MethodOptions final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodOptions) */ { +class PROTOBUF_EXPORT MethodOptions final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.MethodOptions) */ { public: inline MethodOptions() : MethodOptions(nullptr) {} ~MethodOptions() override; - template - explicit PROTOBUF_CONSTEXPR MethodOptions(::google::protobuf::internal::ConstantInitialized); - - inline MethodOptions(const MethodOptions& from) - : MethodOptions(nullptr, from) {} - MethodOptions(MethodOptions&& from) noexcept - : MethodOptions() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR MethodOptions( + ::google::protobuf::internal::ConstantInitialized); + inline MethodOptions(const MethodOptions& from) : MethodOptions(nullptr, from) {} + inline MethodOptions(MethodOptions&& from) noexcept + : MethodOptions(nullptr, std::move(from)) {} inline MethodOptions& operator=(const MethodOptions& from) { CopyFrom(from); return *this; @@ -4414,9 +4303,9 @@ class PROTOBUF_EXPORT MethodOptions final : inline MethodOptions& operator=(MethodOptions&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -4448,22 +4337,17 @@ class PROTOBUF_EXPORT MethodOptions final : } static inline const MethodOptions* internal_default_instance() { return reinterpret_cast( - &_MethodOptions_default_instance_); - } - static constexpr int kIndexInFileMessages = - 22; - - friend void swap(MethodOptions& a, MethodOptions& b) { - a.Swap(&b); + &_MethodOptions_default_instance_); } + static constexpr int kIndexInFileMessages = 22; + friend void swap(MethodOptions& a, MethodOptions& b) { a.Swap(&b); } inline void Swap(MethodOptions* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -4478,16 +4362,18 @@ class PROTOBUF_EXPORT MethodOptions final : // implements Message ---------------------------------------------- MethodOptions* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const MethodOptions& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const MethodOptions& from) { - MethodOptions::MergeImpl(*this, from); - } + void MergeFrom(const MethodOptions& from) { MethodOptions::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -4495,30 +4381,31 @@ class PROTOBUF_EXPORT MethodOptions final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(MethodOptions* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.MethodOptions"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.MethodOptions"; } + + protected: explicit MethodOptions(::google::protobuf::Arena* arena); MethodOptions(::google::protobuf::Arena* arena, const MethodOptions& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + MethodOptions(::google::protobuf::Arena* arena, MethodOptions&& from) noexcept + : MethodOptions(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- - using IdempotencyLevel = MethodOptions_IdempotencyLevel; static constexpr IdempotencyLevel IDEMPOTENCY_UNKNOWN = MethodOptions_IdempotencyLevel_IDEMPOTENCY_UNKNOWN; static constexpr IdempotencyLevel NO_SIDE_EFFECTS = MethodOptions_IdempotencyLevel_NO_SIDE_EFFECTS; @@ -4541,7 +4428,6 @@ class PROTOBUF_EXPORT MethodOptions final : } // accessors ------------------------------------------------------- - enum : int { kUninterpretedOptionFieldNumber = 999, kFeaturesFieldNumber = 35, @@ -4556,16 +4442,15 @@ class PROTOBUF_EXPORT MethodOptions final : public: void clear_uninterpreted_option() ; ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* - mutable_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option(); public: const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& - uninterpreted_option() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const; // optional .google.protobuf.FeatureSet features = 35; bool has_features() const; void clear_features() ; @@ -4783,7 +4668,6 @@ class PROTOBUF_EXPORT MethodOptions final : // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 3, 4, 3, @@ -4795,16 +4679,14 @@ class PROTOBUF_EXPORT MethodOptions final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; @@ -4815,23 +4697,21 @@ class PROTOBUF_EXPORT MethodOptions final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT MessageOptions final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MessageOptions) */ { +class PROTOBUF_EXPORT MessageOptions final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.MessageOptions) */ { public: inline MessageOptions() : MessageOptions(nullptr) {} ~MessageOptions() override; - template - explicit PROTOBUF_CONSTEXPR MessageOptions(::google::protobuf::internal::ConstantInitialized); - - inline MessageOptions(const MessageOptions& from) - : MessageOptions(nullptr, from) {} - MessageOptions(MessageOptions&& from) noexcept - : MessageOptions() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR MessageOptions( + ::google::protobuf::internal::ConstantInitialized); + inline MessageOptions(const MessageOptions& from) : MessageOptions(nullptr, from) {} + inline MessageOptions(MessageOptions&& from) noexcept + : MessageOptions(nullptr, std::move(from)) {} inline MessageOptions& operator=(const MessageOptions& from) { CopyFrom(from); return *this; @@ -4839,9 +4719,9 @@ class PROTOBUF_EXPORT MessageOptions final : inline MessageOptions& operator=(MessageOptions&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -4873,22 +4753,17 @@ class PROTOBUF_EXPORT MessageOptions final : } static inline const MessageOptions* internal_default_instance() { return reinterpret_cast( - &_MessageOptions_default_instance_); - } - static constexpr int kIndexInFileMessages = - 15; - - friend void swap(MessageOptions& a, MessageOptions& b) { - a.Swap(&b); + &_MessageOptions_default_instance_); } + static constexpr int kIndexInFileMessages = 15; + friend void swap(MessageOptions& a, MessageOptions& b) { a.Swap(&b); } inline void Swap(MessageOptions* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -4903,16 +4778,18 @@ class PROTOBUF_EXPORT MessageOptions final : // implements Message ---------------------------------------------- MessageOptions* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const MessageOptions& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const MessageOptions& from) { - MessageOptions::MergeImpl(*this, from); - } + void MergeFrom(const MessageOptions& from) { MessageOptions::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -4920,32 +4797,33 @@ class PROTOBUF_EXPORT MessageOptions final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(MessageOptions* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.MessageOptions"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.MessageOptions"; } + + protected: explicit MessageOptions(::google::protobuf::Arena* arena); MessageOptions(::google::protobuf::Arena* arena, const MessageOptions& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + MessageOptions(::google::protobuf::Arena* arena, MessageOptions&& from) noexcept + : MessageOptions(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kUninterpretedOptionFieldNumber = 999, kFeaturesFieldNumber = 12, @@ -4963,16 +4841,15 @@ class PROTOBUF_EXPORT MessageOptions final : public: void clear_uninterpreted_option() ; ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* - mutable_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option(); public: const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& - uninterpreted_option() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const; // optional .google.protobuf.FeatureSet features = 12; bool has_features() const; void clear_features() ; @@ -5223,7 +5100,6 @@ class PROTOBUF_EXPORT MessageOptions final : // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 3, 7, 2, @@ -5235,16 +5111,14 @@ class PROTOBUF_EXPORT MessageOptions final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; @@ -5258,23 +5132,21 @@ class PROTOBUF_EXPORT MessageOptions final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT FileOptions final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileOptions) */ { +class PROTOBUF_EXPORT FileOptions final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.FileOptions) */ { public: inline FileOptions() : FileOptions(nullptr) {} ~FileOptions() override; - template - explicit PROTOBUF_CONSTEXPR FileOptions(::google::protobuf::internal::ConstantInitialized); - - inline FileOptions(const FileOptions& from) - : FileOptions(nullptr, from) {} - FileOptions(FileOptions&& from) noexcept - : FileOptions() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR FileOptions( + ::google::protobuf::internal::ConstantInitialized); + inline FileOptions(const FileOptions& from) : FileOptions(nullptr, from) {} + inline FileOptions(FileOptions&& from) noexcept + : FileOptions(nullptr, std::move(from)) {} inline FileOptions& operator=(const FileOptions& from) { CopyFrom(from); return *this; @@ -5282,9 +5154,9 @@ class PROTOBUF_EXPORT FileOptions final : inline FileOptions& operator=(FileOptions&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -5316,22 +5188,17 @@ class PROTOBUF_EXPORT FileOptions final : } static inline const FileOptions* internal_default_instance() { return reinterpret_cast( - &_FileOptions_default_instance_); - } - static constexpr int kIndexInFileMessages = - 14; - - friend void swap(FileOptions& a, FileOptions& b) { - a.Swap(&b); + &_FileOptions_default_instance_); } + static constexpr int kIndexInFileMessages = 14; + friend void swap(FileOptions& a, FileOptions& b) { a.Swap(&b); } inline void Swap(FileOptions* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -5346,16 +5213,18 @@ class PROTOBUF_EXPORT FileOptions final : // implements Message ---------------------------------------------- FileOptions* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const FileOptions& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const FileOptions& from) { - FileOptions::MergeImpl(*this, from); - } + void MergeFrom(const FileOptions& from) { FileOptions::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -5363,30 +5232,31 @@ class PROTOBUF_EXPORT FileOptions final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(FileOptions* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.FileOptions"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.FileOptions"; } + + protected: explicit FileOptions(::google::protobuf::Arena* arena); FileOptions(::google::protobuf::Arena* arena, const FileOptions& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + FileOptions(::google::protobuf::Arena* arena, FileOptions&& from) noexcept + : FileOptions(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- - using OptimizeMode = FileOptions_OptimizeMode; static constexpr OptimizeMode SPEED = FileOptions_OptimizeMode_SPEED; static constexpr OptimizeMode CODE_SIZE = FileOptions_OptimizeMode_CODE_SIZE; @@ -5409,7 +5279,6 @@ class PROTOBUF_EXPORT FileOptions final : } // accessors ------------------------------------------------------- - enum : int { kUninterpretedOptionFieldNumber = 999, kJavaPackageFieldNumber = 1, @@ -5442,16 +5311,15 @@ class PROTOBUF_EXPORT FileOptions final : public: void clear_uninterpreted_option() ; ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* - mutable_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option(); public: const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& - uninterpreted_option() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const; // optional string java_package = 1; bool has_java_package() const; void clear_java_package() ; @@ -5927,7 +5795,6 @@ class PROTOBUF_EXPORT FileOptions final : // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 5, 22, 3, @@ -5939,16 +5806,14 @@ class PROTOBUF_EXPORT FileOptions final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; @@ -5977,23 +5842,21 @@ class PROTOBUF_EXPORT FileOptions final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT FieldOptions final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldOptions) */ { +class PROTOBUF_EXPORT FieldOptions final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.FieldOptions) */ { public: inline FieldOptions() : FieldOptions(nullptr) {} ~FieldOptions() override; - template - explicit PROTOBUF_CONSTEXPR FieldOptions(::google::protobuf::internal::ConstantInitialized); - - inline FieldOptions(const FieldOptions& from) - : FieldOptions(nullptr, from) {} - FieldOptions(FieldOptions&& from) noexcept - : FieldOptions() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR FieldOptions( + ::google::protobuf::internal::ConstantInitialized); + inline FieldOptions(const FieldOptions& from) : FieldOptions(nullptr, from) {} + inline FieldOptions(FieldOptions&& from) noexcept + : FieldOptions(nullptr, std::move(from)) {} inline FieldOptions& operator=(const FieldOptions& from) { CopyFrom(from); return *this; @@ -6001,9 +5864,9 @@ class PROTOBUF_EXPORT FieldOptions final : inline FieldOptions& operator=(FieldOptions&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -6035,22 +5898,17 @@ class PROTOBUF_EXPORT FieldOptions final : } static inline const FieldOptions* internal_default_instance() { return reinterpret_cast( - &_FieldOptions_default_instance_); - } - static constexpr int kIndexInFileMessages = - 17; - - friend void swap(FieldOptions& a, FieldOptions& b) { - a.Swap(&b); + &_FieldOptions_default_instance_); } + static constexpr int kIndexInFileMessages = 17; + friend void swap(FieldOptions& a, FieldOptions& b) { a.Swap(&b); } inline void Swap(FieldOptions* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -6065,16 +5923,18 @@ class PROTOBUF_EXPORT FieldOptions final : // implements Message ---------------------------------------------- FieldOptions* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const FieldOptions& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const FieldOptions& from) { - FieldOptions::MergeImpl(*this, from); - } + void MergeFrom(const FieldOptions& from) { FieldOptions::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -6082,32 +5942,32 @@ class PROTOBUF_EXPORT FieldOptions final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(FieldOptions* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.FieldOptions"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.FieldOptions"; } + + protected: explicit FieldOptions(::google::protobuf::Arena* arena); FieldOptions(::google::protobuf::Arena* arena, const FieldOptions& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + FieldOptions(::google::protobuf::Arena* arena, FieldOptions&& from) noexcept + : FieldOptions(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- - using EditionDefault = FieldOptions_EditionDefault; - using CType = FieldOptions_CType; static constexpr CType STRING = FieldOptions_CType_STRING; static constexpr CType CORD = FieldOptions_CType_CORD; @@ -6128,7 +5988,6 @@ class PROTOBUF_EXPORT FieldOptions final : static inline bool CType_Parse(absl::string_view name, CType* value) { return FieldOptions_CType_Parse(name, value); } - using JSType = FieldOptions_JSType; static constexpr JSType JS_NORMAL = FieldOptions_JSType_JS_NORMAL; static constexpr JSType JS_STRING = FieldOptions_JSType_JS_STRING; @@ -6149,7 +6008,6 @@ class PROTOBUF_EXPORT FieldOptions final : static inline bool JSType_Parse(absl::string_view name, JSType* value) { return FieldOptions_JSType_Parse(name, value); } - using OptionRetention = FieldOptions_OptionRetention; static constexpr OptionRetention RETENTION_UNKNOWN = FieldOptions_OptionRetention_RETENTION_UNKNOWN; static constexpr OptionRetention RETENTION_RUNTIME = FieldOptions_OptionRetention_RETENTION_RUNTIME; @@ -6170,7 +6028,6 @@ class PROTOBUF_EXPORT FieldOptions final : static inline bool OptionRetention_Parse(absl::string_view name, OptionRetention* value) { return FieldOptions_OptionRetention_Parse(name, value); } - using OptionTargetType = FieldOptions_OptionTargetType; static constexpr OptionTargetType TARGET_TYPE_UNKNOWN = FieldOptions_OptionTargetType_TARGET_TYPE_UNKNOWN; static constexpr OptionTargetType TARGET_TYPE_FILE = FieldOptions_OptionTargetType_TARGET_TYPE_FILE; @@ -6200,7 +6057,6 @@ class PROTOBUF_EXPORT FieldOptions final : } // accessors ------------------------------------------------------- - enum : int { kTargetsFieldNumber = 19, kEditionDefaultsFieldNumber = 20, @@ -6243,16 +6099,15 @@ class PROTOBUF_EXPORT FieldOptions final : public: void clear_edition_defaults() ; ::google::protobuf::FieldOptions_EditionDefault* mutable_edition_defaults(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldOptions_EditionDefault >* - mutable_edition_defaults(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldOptions_EditionDefault>* mutable_edition_defaults(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldOptions_EditionDefault>& _internal_edition_defaults() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldOptions_EditionDefault>* _internal_mutable_edition_defaults(); public: const ::google::protobuf::FieldOptions_EditionDefault& edition_defaults(int index) const; ::google::protobuf::FieldOptions_EditionDefault* add_edition_defaults(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldOptions_EditionDefault >& - edition_defaults() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldOptions_EditionDefault>& edition_defaults() const; // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; int uninterpreted_option_size() const; private: @@ -6261,16 +6116,15 @@ class PROTOBUF_EXPORT FieldOptions final : public: void clear_uninterpreted_option() ; ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* - mutable_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option(); public: const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& - uninterpreted_option() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const; // optional .google.protobuf.FeatureSet features = 21; bool has_features() const; void clear_features() ; @@ -6565,7 +6419,6 @@ class PROTOBUF_EXPORT FieldOptions final : // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 4, 13, 7, @@ -6577,16 +6430,14 @@ class PROTOBUF_EXPORT FieldOptions final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedField targets_; @@ -6606,23 +6457,21 @@ class PROTOBUF_EXPORT FieldOptions final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT FeatureSetDefaults final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FeatureSetDefaults) */ { +class PROTOBUF_EXPORT FeatureSetDefaults final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.FeatureSetDefaults) */ { public: inline FeatureSetDefaults() : FeatureSetDefaults(nullptr) {} ~FeatureSetDefaults() override; - template - explicit PROTOBUF_CONSTEXPR FeatureSetDefaults(::google::protobuf::internal::ConstantInitialized); - - inline FeatureSetDefaults(const FeatureSetDefaults& from) - : FeatureSetDefaults(nullptr, from) {} - FeatureSetDefaults(FeatureSetDefaults&& from) noexcept - : FeatureSetDefaults() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR FeatureSetDefaults( + ::google::protobuf::internal::ConstantInitialized); + inline FeatureSetDefaults(const FeatureSetDefaults& from) : FeatureSetDefaults(nullptr, from) {} + inline FeatureSetDefaults(FeatureSetDefaults&& from) noexcept + : FeatureSetDefaults(nullptr, std::move(from)) {} inline FeatureSetDefaults& operator=(const FeatureSetDefaults& from) { CopyFrom(from); return *this; @@ -6630,9 +6479,9 @@ class PROTOBUF_EXPORT FeatureSetDefaults final : inline FeatureSetDefaults& operator=(FeatureSetDefaults&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -6664,22 +6513,17 @@ class PROTOBUF_EXPORT FeatureSetDefaults final : } static inline const FeatureSetDefaults* internal_default_instance() { return reinterpret_cast( - &_FeatureSetDefaults_default_instance_); - } - static constexpr int kIndexInFileMessages = - 27; - - friend void swap(FeatureSetDefaults& a, FeatureSetDefaults& b) { - a.Swap(&b); + &_FeatureSetDefaults_default_instance_); } + static constexpr int kIndexInFileMessages = 27; + friend void swap(FeatureSetDefaults& a, FeatureSetDefaults& b) { a.Swap(&b); } inline void Swap(FeatureSetDefaults* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -6694,16 +6538,18 @@ class PROTOBUF_EXPORT FeatureSetDefaults final : // implements Message ---------------------------------------------- FeatureSetDefaults* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const FeatureSetDefaults& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const FeatureSetDefaults& from) { - FeatureSetDefaults::MergeImpl(*this, from); - } + void MergeFrom(const FeatureSetDefaults& from) { FeatureSetDefaults::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -6711,34 +6557,34 @@ class PROTOBUF_EXPORT FeatureSetDefaults final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(FeatureSetDefaults* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.FeatureSetDefaults"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.FeatureSetDefaults"; } + + protected: explicit FeatureSetDefaults(::google::protobuf::Arena* arena); FeatureSetDefaults(::google::protobuf::Arena* arena, const FeatureSetDefaults& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + FeatureSetDefaults(::google::protobuf::Arena* arena, FeatureSetDefaults&& from) noexcept + : FeatureSetDefaults(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- - using FeatureSetEditionDefault = FeatureSetDefaults_FeatureSetEditionDefault; // accessors ------------------------------------------------------- - enum : int { kDefaultsFieldNumber = 1, kMinimumEditionFieldNumber = 4, @@ -6752,16 +6598,15 @@ class PROTOBUF_EXPORT FeatureSetDefaults final : public: void clear_defaults() ; ::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault* mutable_defaults(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault >* - mutable_defaults(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault>* mutable_defaults(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault>& _internal_defaults() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault>* _internal_mutable_defaults(); public: const ::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault& defaults(int index) const; ::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault* add_defaults(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault >& - defaults() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault>& defaults() const; // optional .google.protobuf.Edition minimum_edition = 4; bool has_minimum_edition() const; void clear_minimum_edition() ; @@ -6787,7 +6632,6 @@ class PROTOBUF_EXPORT FeatureSetDefaults final : // @@protoc_insertion_point(class_scope:google.protobuf.FeatureSetDefaults) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 1, 3, 3, @@ -6799,14 +6643,13 @@ class PROTOBUF_EXPORT FeatureSetDefaults final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault > defaults_; @@ -6816,23 +6659,21 @@ class PROTOBUF_EXPORT FeatureSetDefaults final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT ExtensionRangeOptions final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ExtensionRangeOptions) */ { +class PROTOBUF_EXPORT ExtensionRangeOptions final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.ExtensionRangeOptions) */ { public: inline ExtensionRangeOptions() : ExtensionRangeOptions(nullptr) {} ~ExtensionRangeOptions() override; - template - explicit PROTOBUF_CONSTEXPR ExtensionRangeOptions(::google::protobuf::internal::ConstantInitialized); - - inline ExtensionRangeOptions(const ExtensionRangeOptions& from) - : ExtensionRangeOptions(nullptr, from) {} - ExtensionRangeOptions(ExtensionRangeOptions&& from) noexcept - : ExtensionRangeOptions() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR ExtensionRangeOptions( + ::google::protobuf::internal::ConstantInitialized); + inline ExtensionRangeOptions(const ExtensionRangeOptions& from) : ExtensionRangeOptions(nullptr, from) {} + inline ExtensionRangeOptions(ExtensionRangeOptions&& from) noexcept + : ExtensionRangeOptions(nullptr, std::move(from)) {} inline ExtensionRangeOptions& operator=(const ExtensionRangeOptions& from) { CopyFrom(from); return *this; @@ -6840,9 +6681,9 @@ class PROTOBUF_EXPORT ExtensionRangeOptions final : inline ExtensionRangeOptions& operator=(ExtensionRangeOptions&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -6874,22 +6715,17 @@ class PROTOBUF_EXPORT ExtensionRangeOptions final : } static inline const ExtensionRangeOptions* internal_default_instance() { return reinterpret_cast( - &_ExtensionRangeOptions_default_instance_); - } - static constexpr int kIndexInFileMessages = - 6; - - friend void swap(ExtensionRangeOptions& a, ExtensionRangeOptions& b) { - a.Swap(&b); + &_ExtensionRangeOptions_default_instance_); } + static constexpr int kIndexInFileMessages = 6; + friend void swap(ExtensionRangeOptions& a, ExtensionRangeOptions& b) { a.Swap(&b); } inline void Swap(ExtensionRangeOptions* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -6904,16 +6740,18 @@ class PROTOBUF_EXPORT ExtensionRangeOptions final : // implements Message ---------------------------------------------- ExtensionRangeOptions* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const ExtensionRangeOptions& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const ExtensionRangeOptions& from) { - ExtensionRangeOptions::MergeImpl(*this, from); - } + void MergeFrom(const ExtensionRangeOptions& from) { ExtensionRangeOptions::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -6921,32 +6759,32 @@ class PROTOBUF_EXPORT ExtensionRangeOptions final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(ExtensionRangeOptions* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.ExtensionRangeOptions"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.ExtensionRangeOptions"; } + + protected: explicit ExtensionRangeOptions(::google::protobuf::Arena* arena); ExtensionRangeOptions(::google::protobuf::Arena* arena, const ExtensionRangeOptions& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + ExtensionRangeOptions(::google::protobuf::Arena* arena, ExtensionRangeOptions&& from) noexcept + : ExtensionRangeOptions(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- - using Declaration = ExtensionRangeOptions_Declaration; - using VerificationState = ExtensionRangeOptions_VerificationState; static constexpr VerificationState DECLARATION = ExtensionRangeOptions_VerificationState_DECLARATION; static constexpr VerificationState UNVERIFIED = ExtensionRangeOptions_VerificationState_UNVERIFIED; @@ -6968,7 +6806,6 @@ class PROTOBUF_EXPORT ExtensionRangeOptions final : } // accessors ------------------------------------------------------- - enum : int { kDeclarationFieldNumber = 2, kUninterpretedOptionFieldNumber = 999, @@ -6983,16 +6820,15 @@ class PROTOBUF_EXPORT ExtensionRangeOptions final : public: void clear_declaration() ; ::google::protobuf::ExtensionRangeOptions_Declaration* mutable_declaration(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::ExtensionRangeOptions_Declaration >* - mutable_declaration(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::ExtensionRangeOptions_Declaration>* mutable_declaration(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::ExtensionRangeOptions_Declaration>& _internal_declaration() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::ExtensionRangeOptions_Declaration>* _internal_mutable_declaration(); public: const ::google::protobuf::ExtensionRangeOptions_Declaration& declaration(int index) const; ::google::protobuf::ExtensionRangeOptions_Declaration* add_declaration(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ExtensionRangeOptions_Declaration >& - declaration() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::ExtensionRangeOptions_Declaration>& declaration() const; // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; int uninterpreted_option_size() const; private: @@ -7001,16 +6837,15 @@ class PROTOBUF_EXPORT ExtensionRangeOptions final : public: void clear_uninterpreted_option() ; ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* - mutable_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option(); public: const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& - uninterpreted_option() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const; // optional .google.protobuf.FeatureSet features = 50; bool has_features() const; void clear_features() ; @@ -7026,7 +6861,7 @@ class PROTOBUF_EXPORT ExtensionRangeOptions final : ::google::protobuf::FeatureSet* _internal_mutable_features(); public: - // optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED]; + // optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED, retention = RETENTION_SOURCE]; bool has_verification() const; void clear_verification() ; ::google::protobuf::ExtensionRangeOptions_VerificationState verification() const; @@ -7217,7 +7052,6 @@ class PROTOBUF_EXPORT ExtensionRangeOptions final : // @@protoc_insertion_point(class_scope:google.protobuf.ExtensionRangeOptions) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 3, 4, 4, @@ -7229,16 +7063,14 @@ class PROTOBUF_EXPORT ExtensionRangeOptions final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::ExtensionRangeOptions_Declaration > declaration_; @@ -7249,23 +7081,21 @@ class PROTOBUF_EXPORT ExtensionRangeOptions final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT EnumValueOptions final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueOptions) */ { +class PROTOBUF_EXPORT EnumValueOptions final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueOptions) */ { public: inline EnumValueOptions() : EnumValueOptions(nullptr) {} ~EnumValueOptions() override; - template - explicit PROTOBUF_CONSTEXPR EnumValueOptions(::google::protobuf::internal::ConstantInitialized); - - inline EnumValueOptions(const EnumValueOptions& from) - : EnumValueOptions(nullptr, from) {} - EnumValueOptions(EnumValueOptions&& from) noexcept - : EnumValueOptions() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR EnumValueOptions( + ::google::protobuf::internal::ConstantInitialized); + inline EnumValueOptions(const EnumValueOptions& from) : EnumValueOptions(nullptr, from) {} + inline EnumValueOptions(EnumValueOptions&& from) noexcept + : EnumValueOptions(nullptr, std::move(from)) {} inline EnumValueOptions& operator=(const EnumValueOptions& from) { CopyFrom(from); return *this; @@ -7273,9 +7103,9 @@ class PROTOBUF_EXPORT EnumValueOptions final : inline EnumValueOptions& operator=(EnumValueOptions&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -7307,22 +7137,17 @@ class PROTOBUF_EXPORT EnumValueOptions final : } static inline const EnumValueOptions* internal_default_instance() { return reinterpret_cast( - &_EnumValueOptions_default_instance_); - } - static constexpr int kIndexInFileMessages = - 20; - - friend void swap(EnumValueOptions& a, EnumValueOptions& b) { - a.Swap(&b); + &_EnumValueOptions_default_instance_); } + static constexpr int kIndexInFileMessages = 20; + friend void swap(EnumValueOptions& a, EnumValueOptions& b) { a.Swap(&b); } inline void Swap(EnumValueOptions* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -7337,16 +7162,18 @@ class PROTOBUF_EXPORT EnumValueOptions final : // implements Message ---------------------------------------------- EnumValueOptions* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const EnumValueOptions& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const EnumValueOptions& from) { - EnumValueOptions::MergeImpl(*this, from); - } + void MergeFrom(const EnumValueOptions& from) { EnumValueOptions::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -7354,32 +7181,33 @@ class PROTOBUF_EXPORT EnumValueOptions final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(EnumValueOptions* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.EnumValueOptions"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.EnumValueOptions"; } + + protected: explicit EnumValueOptions(::google::protobuf::Arena* arena); EnumValueOptions(::google::protobuf::Arena* arena, const EnumValueOptions& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + EnumValueOptions(::google::protobuf::Arena* arena, EnumValueOptions&& from) noexcept + : EnumValueOptions(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kUninterpretedOptionFieldNumber = 999, kFeaturesFieldNumber = 2, @@ -7394,16 +7222,15 @@ class PROTOBUF_EXPORT EnumValueOptions final : public: void clear_uninterpreted_option() ; ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* - mutable_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option(); public: const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& - uninterpreted_option() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const; // optional .google.protobuf.FeatureSet features = 2; bool has_features() const; void clear_features() ; @@ -7621,7 +7448,6 @@ class PROTOBUF_EXPORT EnumValueOptions final : // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 3, 4, 2, @@ -7633,16 +7459,14 @@ class PROTOBUF_EXPORT EnumValueOptions final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; @@ -7653,23 +7477,21 @@ class PROTOBUF_EXPORT EnumValueOptions final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT EnumOptions final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumOptions) */ { +class PROTOBUF_EXPORT EnumOptions final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.EnumOptions) */ { public: inline EnumOptions() : EnumOptions(nullptr) {} ~EnumOptions() override; - template - explicit PROTOBUF_CONSTEXPR EnumOptions(::google::protobuf::internal::ConstantInitialized); - - inline EnumOptions(const EnumOptions& from) - : EnumOptions(nullptr, from) {} - EnumOptions(EnumOptions&& from) noexcept - : EnumOptions() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR EnumOptions( + ::google::protobuf::internal::ConstantInitialized); + inline EnumOptions(const EnumOptions& from) : EnumOptions(nullptr, from) {} + inline EnumOptions(EnumOptions&& from) noexcept + : EnumOptions(nullptr, std::move(from)) {} inline EnumOptions& operator=(const EnumOptions& from) { CopyFrom(from); return *this; @@ -7677,9 +7499,9 @@ class PROTOBUF_EXPORT EnumOptions final : inline EnumOptions& operator=(EnumOptions&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -7711,22 +7533,17 @@ class PROTOBUF_EXPORT EnumOptions final : } static inline const EnumOptions* internal_default_instance() { return reinterpret_cast( - &_EnumOptions_default_instance_); - } - static constexpr int kIndexInFileMessages = - 19; - - friend void swap(EnumOptions& a, EnumOptions& b) { - a.Swap(&b); + &_EnumOptions_default_instance_); } + static constexpr int kIndexInFileMessages = 19; + friend void swap(EnumOptions& a, EnumOptions& b) { a.Swap(&b); } inline void Swap(EnumOptions* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -7741,16 +7558,18 @@ class PROTOBUF_EXPORT EnumOptions final : // implements Message ---------------------------------------------- EnumOptions* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const EnumOptions& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const EnumOptions& from) { - EnumOptions::MergeImpl(*this, from); - } + void MergeFrom(const EnumOptions& from) { EnumOptions::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -7758,32 +7577,33 @@ class PROTOBUF_EXPORT EnumOptions final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(EnumOptions* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.EnumOptions"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.EnumOptions"; } + + protected: explicit EnumOptions(::google::protobuf::Arena* arena); EnumOptions(::google::protobuf::Arena* arena, const EnumOptions& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + EnumOptions(::google::protobuf::Arena* arena, EnumOptions&& from) noexcept + : EnumOptions(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kUninterpretedOptionFieldNumber = 999, kFeaturesFieldNumber = 7, @@ -7799,16 +7619,15 @@ class PROTOBUF_EXPORT EnumOptions final : public: void clear_uninterpreted_option() ; ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >* - mutable_uninterpreted_option(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* mutable_uninterpreted_option(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& _internal_uninterpreted_option() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* _internal_mutable_uninterpreted_option(); public: const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const; ::google::protobuf::UninterpretedOption* add_uninterpreted_option(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >& - uninterpreted_option() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& uninterpreted_option() const; // optional .google.protobuf.FeatureSet features = 7; bool has_features() const; void clear_features() ; @@ -8037,7 +7856,6 @@ class PROTOBUF_EXPORT EnumOptions final : // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 3, 5, 2, @@ -8049,16 +7867,14 @@ class PROTOBUF_EXPORT EnumOptions final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::ExtensionSet _extensions_; - ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; @@ -8070,23 +7886,21 @@ class PROTOBUF_EXPORT EnumOptions final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT OneofDescriptorProto final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.OneofDescriptorProto) */ { +class PROTOBUF_EXPORT OneofDescriptorProto final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.OneofDescriptorProto) */ { public: inline OneofDescriptorProto() : OneofDescriptorProto(nullptr) {} ~OneofDescriptorProto() override; - template - explicit PROTOBUF_CONSTEXPR OneofDescriptorProto(::google::protobuf::internal::ConstantInitialized); - - inline OneofDescriptorProto(const OneofDescriptorProto& from) - : OneofDescriptorProto(nullptr, from) {} - OneofDescriptorProto(OneofDescriptorProto&& from) noexcept - : OneofDescriptorProto() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR OneofDescriptorProto( + ::google::protobuf::internal::ConstantInitialized); + inline OneofDescriptorProto(const OneofDescriptorProto& from) : OneofDescriptorProto(nullptr, from) {} + inline OneofDescriptorProto(OneofDescriptorProto&& from) noexcept + : OneofDescriptorProto(nullptr, std::move(from)) {} inline OneofDescriptorProto& operator=(const OneofDescriptorProto& from) { CopyFrom(from); return *this; @@ -8094,9 +7908,9 @@ class PROTOBUF_EXPORT OneofDescriptorProto final : inline OneofDescriptorProto& operator=(OneofDescriptorProto&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -8128,22 +7942,17 @@ class PROTOBUF_EXPORT OneofDescriptorProto final : } static inline const OneofDescriptorProto* internal_default_instance() { return reinterpret_cast( - &_OneofDescriptorProto_default_instance_); - } - static constexpr int kIndexInFileMessages = - 8; - - friend void swap(OneofDescriptorProto& a, OneofDescriptorProto& b) { - a.Swap(&b); + &_OneofDescriptorProto_default_instance_); } + static constexpr int kIndexInFileMessages = 8; + friend void swap(OneofDescriptorProto& a, OneofDescriptorProto& b) { a.Swap(&b); } inline void Swap(OneofDescriptorProto* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -8158,16 +7967,18 @@ class PROTOBUF_EXPORT OneofDescriptorProto final : // implements Message ---------------------------------------------- OneofDescriptorProto* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const OneofDescriptorProto& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const OneofDescriptorProto& from) { - OneofDescriptorProto::MergeImpl(*this, from); - } + void MergeFrom(const OneofDescriptorProto& from) { OneofDescriptorProto::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -8175,32 +7986,33 @@ class PROTOBUF_EXPORT OneofDescriptorProto final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(OneofDescriptorProto* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.OneofDescriptorProto"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.OneofDescriptorProto"; } + + protected: explicit OneofDescriptorProto(::google::protobuf::Arena* arena); OneofDescriptorProto(::google::protobuf::Arena* arena, const OneofDescriptorProto& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + OneofDescriptorProto(::google::protobuf::Arena* arena, OneofDescriptorProto&& from) noexcept + : OneofDescriptorProto(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kNameFieldNumber = 1, kOptionsFieldNumber = 2, @@ -8240,7 +8052,6 @@ class PROTOBUF_EXPORT OneofDescriptorProto final : // @@protoc_insertion_point(class_scope:google.protobuf.OneofDescriptorProto) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 1, 2, 1, @@ -8252,14 +8063,13 @@ class PROTOBUF_EXPORT OneofDescriptorProto final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::internal::ArenaStringPtr name_; @@ -8268,23 +8078,21 @@ class PROTOBUF_EXPORT OneofDescriptorProto final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT MethodDescriptorProto final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.MethodDescriptorProto) */ { +class PROTOBUF_EXPORT MethodDescriptorProto final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.MethodDescriptorProto) */ { public: inline MethodDescriptorProto() : MethodDescriptorProto(nullptr) {} ~MethodDescriptorProto() override; - template - explicit PROTOBUF_CONSTEXPR MethodDescriptorProto(::google::protobuf::internal::ConstantInitialized); - - inline MethodDescriptorProto(const MethodDescriptorProto& from) - : MethodDescriptorProto(nullptr, from) {} - MethodDescriptorProto(MethodDescriptorProto&& from) noexcept - : MethodDescriptorProto() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR MethodDescriptorProto( + ::google::protobuf::internal::ConstantInitialized); + inline MethodDescriptorProto(const MethodDescriptorProto& from) : MethodDescriptorProto(nullptr, from) {} + inline MethodDescriptorProto(MethodDescriptorProto&& from) noexcept + : MethodDescriptorProto(nullptr, std::move(from)) {} inline MethodDescriptorProto& operator=(const MethodDescriptorProto& from) { CopyFrom(from); return *this; @@ -8292,9 +8100,9 @@ class PROTOBUF_EXPORT MethodDescriptorProto final : inline MethodDescriptorProto& operator=(MethodDescriptorProto&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -8326,22 +8134,17 @@ class PROTOBUF_EXPORT MethodDescriptorProto final : } static inline const MethodDescriptorProto* internal_default_instance() { return reinterpret_cast( - &_MethodDescriptorProto_default_instance_); - } - static constexpr int kIndexInFileMessages = - 13; - - friend void swap(MethodDescriptorProto& a, MethodDescriptorProto& b) { - a.Swap(&b); + &_MethodDescriptorProto_default_instance_); } + static constexpr int kIndexInFileMessages = 13; + friend void swap(MethodDescriptorProto& a, MethodDescriptorProto& b) { a.Swap(&b); } inline void Swap(MethodDescriptorProto* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -8356,16 +8159,18 @@ class PROTOBUF_EXPORT MethodDescriptorProto final : // implements Message ---------------------------------------------- MethodDescriptorProto* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const MethodDescriptorProto& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const MethodDescriptorProto& from) { - MethodDescriptorProto::MergeImpl(*this, from); - } + void MergeFrom(const MethodDescriptorProto& from) { MethodDescriptorProto::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -8373,32 +8178,33 @@ class PROTOBUF_EXPORT MethodDescriptorProto final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(MethodDescriptorProto* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.MethodDescriptorProto"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.MethodDescriptorProto"; } + + protected: explicit MethodDescriptorProto(::google::protobuf::Arena* arena); MethodDescriptorProto(::google::protobuf::Arena* arena, const MethodDescriptorProto& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + MethodDescriptorProto(::google::protobuf::Arena* arena, MethodDescriptorProto&& from) noexcept + : MethodDescriptorProto(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kNameFieldNumber = 1, kInputTypeFieldNumber = 2, @@ -8498,7 +8304,6 @@ class PROTOBUF_EXPORT MethodDescriptorProto final : // @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 3, 6, 1, @@ -8510,14 +8315,13 @@ class PROTOBUF_EXPORT MethodDescriptorProto final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::internal::ArenaStringPtr name_; @@ -8530,23 +8334,21 @@ class PROTOBUF_EXPORT MethodDescriptorProto final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT FieldDescriptorProto final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldDescriptorProto) */ { +class PROTOBUF_EXPORT FieldDescriptorProto final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.FieldDescriptorProto) */ { public: inline FieldDescriptorProto() : FieldDescriptorProto(nullptr) {} ~FieldDescriptorProto() override; - template - explicit PROTOBUF_CONSTEXPR FieldDescriptorProto(::google::protobuf::internal::ConstantInitialized); - - inline FieldDescriptorProto(const FieldDescriptorProto& from) - : FieldDescriptorProto(nullptr, from) {} - FieldDescriptorProto(FieldDescriptorProto&& from) noexcept - : FieldDescriptorProto() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR FieldDescriptorProto( + ::google::protobuf::internal::ConstantInitialized); + inline FieldDescriptorProto(const FieldDescriptorProto& from) : FieldDescriptorProto(nullptr, from) {} + inline FieldDescriptorProto(FieldDescriptorProto&& from) noexcept + : FieldDescriptorProto(nullptr, std::move(from)) {} inline FieldDescriptorProto& operator=(const FieldDescriptorProto& from) { CopyFrom(from); return *this; @@ -8554,9 +8356,9 @@ class PROTOBUF_EXPORT FieldDescriptorProto final : inline FieldDescriptorProto& operator=(FieldDescriptorProto&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -8588,22 +8390,17 @@ class PROTOBUF_EXPORT FieldDescriptorProto final : } static inline const FieldDescriptorProto* internal_default_instance() { return reinterpret_cast( - &_FieldDescriptorProto_default_instance_); - } - static constexpr int kIndexInFileMessages = - 7; - - friend void swap(FieldDescriptorProto& a, FieldDescriptorProto& b) { - a.Swap(&b); + &_FieldDescriptorProto_default_instance_); } + static constexpr int kIndexInFileMessages = 7; + friend void swap(FieldDescriptorProto& a, FieldDescriptorProto& b) { a.Swap(&b); } inline void Swap(FieldDescriptorProto* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -8618,16 +8415,18 @@ class PROTOBUF_EXPORT FieldDescriptorProto final : // implements Message ---------------------------------------------- FieldDescriptorProto* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const FieldDescriptorProto& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const FieldDescriptorProto& from) { - FieldDescriptorProto::MergeImpl(*this, from); - } + void MergeFrom(const FieldDescriptorProto& from) { FieldDescriptorProto::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -8635,30 +8434,31 @@ class PROTOBUF_EXPORT FieldDescriptorProto final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(FieldDescriptorProto* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.FieldDescriptorProto"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.FieldDescriptorProto"; } + + protected: explicit FieldDescriptorProto(::google::protobuf::Arena* arena); FieldDescriptorProto(::google::protobuf::Arena* arena, const FieldDescriptorProto& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + FieldDescriptorProto(::google::protobuf::Arena* arena, FieldDescriptorProto&& from) noexcept + : FieldDescriptorProto(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- - using Type = FieldDescriptorProto_Type; static constexpr Type TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE; static constexpr Type TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT; @@ -8694,7 +8494,6 @@ class PROTOBUF_EXPORT FieldDescriptorProto final : static inline bool Type_Parse(absl::string_view name, Type* value) { return FieldDescriptorProto_Type_Parse(name, value); } - using Label = FieldDescriptorProto_Label; static constexpr Label LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL; static constexpr Label LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED; @@ -8717,7 +8516,6 @@ class PROTOBUF_EXPORT FieldDescriptorProto final : } // accessors ------------------------------------------------------- - enum : int { kNameFieldNumber = 1, kExtendeeFieldNumber = 2, @@ -8889,7 +8687,6 @@ class PROTOBUF_EXPORT FieldDescriptorProto final : // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 4, 11, 3, @@ -8901,14 +8698,13 @@ class PROTOBUF_EXPORT FieldDescriptorProto final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::internal::ArenaStringPtr name_; @@ -8926,23 +8722,21 @@ class PROTOBUF_EXPORT FieldDescriptorProto final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT EnumValueDescriptorProto final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueDescriptorProto) */ { +class PROTOBUF_EXPORT EnumValueDescriptorProto final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.EnumValueDescriptorProto) */ { public: inline EnumValueDescriptorProto() : EnumValueDescriptorProto(nullptr) {} ~EnumValueDescriptorProto() override; - template - explicit PROTOBUF_CONSTEXPR EnumValueDescriptorProto(::google::protobuf::internal::ConstantInitialized); - - inline EnumValueDescriptorProto(const EnumValueDescriptorProto& from) - : EnumValueDescriptorProto(nullptr, from) {} - EnumValueDescriptorProto(EnumValueDescriptorProto&& from) noexcept - : EnumValueDescriptorProto() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR EnumValueDescriptorProto( + ::google::protobuf::internal::ConstantInitialized); + inline EnumValueDescriptorProto(const EnumValueDescriptorProto& from) : EnumValueDescriptorProto(nullptr, from) {} + inline EnumValueDescriptorProto(EnumValueDescriptorProto&& from) noexcept + : EnumValueDescriptorProto(nullptr, std::move(from)) {} inline EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto& from) { CopyFrom(from); return *this; @@ -8950,9 +8744,9 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto final : inline EnumValueDescriptorProto& operator=(EnumValueDescriptorProto&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -8984,22 +8778,17 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto final : } static inline const EnumValueDescriptorProto* internal_default_instance() { return reinterpret_cast( - &_EnumValueDescriptorProto_default_instance_); - } - static constexpr int kIndexInFileMessages = - 11; - - friend void swap(EnumValueDescriptorProto& a, EnumValueDescriptorProto& b) { - a.Swap(&b); + &_EnumValueDescriptorProto_default_instance_); } + static constexpr int kIndexInFileMessages = 11; + friend void swap(EnumValueDescriptorProto& a, EnumValueDescriptorProto& b) { a.Swap(&b); } inline void Swap(EnumValueDescriptorProto* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -9014,16 +8803,18 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto final : // implements Message ---------------------------------------------- EnumValueDescriptorProto* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const EnumValueDescriptorProto& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const EnumValueDescriptorProto& from) { - EnumValueDescriptorProto::MergeImpl(*this, from); - } + void MergeFrom(const EnumValueDescriptorProto& from) { EnumValueDescriptorProto::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -9031,32 +8822,33 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(EnumValueDescriptorProto* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.EnumValueDescriptorProto"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.EnumValueDescriptorProto"; } + + protected: explicit EnumValueDescriptorProto(::google::protobuf::Arena* arena); EnumValueDescriptorProto(::google::protobuf::Arena* arena, const EnumValueDescriptorProto& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + EnumValueDescriptorProto(::google::protobuf::Arena* arena, EnumValueDescriptorProto&& from) noexcept + : EnumValueDescriptorProto(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kNameFieldNumber = 1, kOptionsFieldNumber = 3, @@ -9108,7 +8900,6 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto final : // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 2, 3, 1, @@ -9120,14 +8911,13 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::internal::ArenaStringPtr name_; @@ -9137,23 +8927,21 @@ class PROTOBUF_EXPORT EnumValueDescriptorProto final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT DescriptorProto_ExtensionRange final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ExtensionRange) */ { +class PROTOBUF_EXPORT DescriptorProto_ExtensionRange final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto.ExtensionRange) */ { public: inline DescriptorProto_ExtensionRange() : DescriptorProto_ExtensionRange(nullptr) {} ~DescriptorProto_ExtensionRange() override; - template - explicit PROTOBUF_CONSTEXPR DescriptorProto_ExtensionRange(::google::protobuf::internal::ConstantInitialized); - - inline DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from) - : DescriptorProto_ExtensionRange(nullptr, from) {} - DescriptorProto_ExtensionRange(DescriptorProto_ExtensionRange&& from) noexcept - : DescriptorProto_ExtensionRange() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR DescriptorProto_ExtensionRange( + ::google::protobuf::internal::ConstantInitialized); + inline DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from) : DescriptorProto_ExtensionRange(nullptr, from) {} + inline DescriptorProto_ExtensionRange(DescriptorProto_ExtensionRange&& from) noexcept + : DescriptorProto_ExtensionRange(nullptr, std::move(from)) {} inline DescriptorProto_ExtensionRange& operator=(const DescriptorProto_ExtensionRange& from) { CopyFrom(from); return *this; @@ -9161,9 +8949,9 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange final : inline DescriptorProto_ExtensionRange& operator=(DescriptorProto_ExtensionRange&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -9195,22 +8983,17 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange final : } static inline const DescriptorProto_ExtensionRange* internal_default_instance() { return reinterpret_cast( - &_DescriptorProto_ExtensionRange_default_instance_); - } - static constexpr int kIndexInFileMessages = - 2; - - friend void swap(DescriptorProto_ExtensionRange& a, DescriptorProto_ExtensionRange& b) { - a.Swap(&b); + &_DescriptorProto_ExtensionRange_default_instance_); } + static constexpr int kIndexInFileMessages = 2; + friend void swap(DescriptorProto_ExtensionRange& a, DescriptorProto_ExtensionRange& b) { a.Swap(&b); } inline void Swap(DescriptorProto_ExtensionRange* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -9225,16 +9008,18 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange final : // implements Message ---------------------------------------------- DescriptorProto_ExtensionRange* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const DescriptorProto_ExtensionRange& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const DescriptorProto_ExtensionRange& from) { - DescriptorProto_ExtensionRange::MergeImpl(*this, from); - } + void MergeFrom(const DescriptorProto_ExtensionRange& from) { DescriptorProto_ExtensionRange::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -9242,32 +9027,33 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(DescriptorProto_ExtensionRange* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.DescriptorProto.ExtensionRange"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.DescriptorProto.ExtensionRange"; } + + protected: explicit DescriptorProto_ExtensionRange(::google::protobuf::Arena* arena); DescriptorProto_ExtensionRange(::google::protobuf::Arena* arena, const DescriptorProto_ExtensionRange& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + DescriptorProto_ExtensionRange(::google::protobuf::Arena* arena, DescriptorProto_ExtensionRange&& from) noexcept + : DescriptorProto_ExtensionRange(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kOptionsFieldNumber = 3, kStartFieldNumber = 1, @@ -9313,7 +9099,6 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange final : // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 2, 3, 1, @@ -9325,14 +9110,13 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::ExtensionRangeOptions* options_; @@ -9342,23 +9126,21 @@ class PROTOBUF_EXPORT DescriptorProto_ExtensionRange final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT ServiceDescriptorProto final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ServiceDescriptorProto) */ { +class PROTOBUF_EXPORT ServiceDescriptorProto final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.ServiceDescriptorProto) */ { public: inline ServiceDescriptorProto() : ServiceDescriptorProto(nullptr) {} ~ServiceDescriptorProto() override; - template - explicit PROTOBUF_CONSTEXPR ServiceDescriptorProto(::google::protobuf::internal::ConstantInitialized); - - inline ServiceDescriptorProto(const ServiceDescriptorProto& from) - : ServiceDescriptorProto(nullptr, from) {} - ServiceDescriptorProto(ServiceDescriptorProto&& from) noexcept - : ServiceDescriptorProto() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR ServiceDescriptorProto( + ::google::protobuf::internal::ConstantInitialized); + inline ServiceDescriptorProto(const ServiceDescriptorProto& from) : ServiceDescriptorProto(nullptr, from) {} + inline ServiceDescriptorProto(ServiceDescriptorProto&& from) noexcept + : ServiceDescriptorProto(nullptr, std::move(from)) {} inline ServiceDescriptorProto& operator=(const ServiceDescriptorProto& from) { CopyFrom(from); return *this; @@ -9366,9 +9148,9 @@ class PROTOBUF_EXPORT ServiceDescriptorProto final : inline ServiceDescriptorProto& operator=(ServiceDescriptorProto&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -9400,22 +9182,17 @@ class PROTOBUF_EXPORT ServiceDescriptorProto final : } static inline const ServiceDescriptorProto* internal_default_instance() { return reinterpret_cast( - &_ServiceDescriptorProto_default_instance_); - } - static constexpr int kIndexInFileMessages = - 12; - - friend void swap(ServiceDescriptorProto& a, ServiceDescriptorProto& b) { - a.Swap(&b); + &_ServiceDescriptorProto_default_instance_); } + static constexpr int kIndexInFileMessages = 12; + friend void swap(ServiceDescriptorProto& a, ServiceDescriptorProto& b) { a.Swap(&b); } inline void Swap(ServiceDescriptorProto* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -9430,16 +9207,18 @@ class PROTOBUF_EXPORT ServiceDescriptorProto final : // implements Message ---------------------------------------------- ServiceDescriptorProto* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const ServiceDescriptorProto& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const ServiceDescriptorProto& from) { - ServiceDescriptorProto::MergeImpl(*this, from); - } + void MergeFrom(const ServiceDescriptorProto& from) { ServiceDescriptorProto::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -9447,32 +9226,33 @@ class PROTOBUF_EXPORT ServiceDescriptorProto final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(ServiceDescriptorProto* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.ServiceDescriptorProto"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.ServiceDescriptorProto"; } + + protected: explicit ServiceDescriptorProto(::google::protobuf::Arena* arena); ServiceDescriptorProto(::google::protobuf::Arena* arena, const ServiceDescriptorProto& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + ServiceDescriptorProto(::google::protobuf::Arena* arena, ServiceDescriptorProto&& from) noexcept + : ServiceDescriptorProto(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kMethodFieldNumber = 2, kNameFieldNumber = 1, @@ -9486,16 +9266,15 @@ class PROTOBUF_EXPORT ServiceDescriptorProto final : public: void clear_method() ; ::google::protobuf::MethodDescriptorProto* mutable_method(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >* - mutable_method(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::MethodDescriptorProto>* mutable_method(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::MethodDescriptorProto>& _internal_method() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::MethodDescriptorProto>* _internal_mutable_method(); public: const ::google::protobuf::MethodDescriptorProto& method(int index) const; ::google::protobuf::MethodDescriptorProto* add_method(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >& - method() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::MethodDescriptorProto>& method() const; // optional string name = 1; bool has_name() const; void clear_name() ; @@ -9531,7 +9310,6 @@ class PROTOBUF_EXPORT ServiceDescriptorProto final : // @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 2, 3, 2, @@ -9543,14 +9321,13 @@ class PROTOBUF_EXPORT ServiceDescriptorProto final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_; @@ -9560,23 +9337,21 @@ class PROTOBUF_EXPORT ServiceDescriptorProto final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT EnumDescriptorProto final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto) */ { +class PROTOBUF_EXPORT EnumDescriptorProto final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.EnumDescriptorProto) */ { public: inline EnumDescriptorProto() : EnumDescriptorProto(nullptr) {} ~EnumDescriptorProto() override; - template - explicit PROTOBUF_CONSTEXPR EnumDescriptorProto(::google::protobuf::internal::ConstantInitialized); - - inline EnumDescriptorProto(const EnumDescriptorProto& from) - : EnumDescriptorProto(nullptr, from) {} - EnumDescriptorProto(EnumDescriptorProto&& from) noexcept - : EnumDescriptorProto() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR EnumDescriptorProto( + ::google::protobuf::internal::ConstantInitialized); + inline EnumDescriptorProto(const EnumDescriptorProto& from) : EnumDescriptorProto(nullptr, from) {} + inline EnumDescriptorProto(EnumDescriptorProto&& from) noexcept + : EnumDescriptorProto(nullptr, std::move(from)) {} inline EnumDescriptorProto& operator=(const EnumDescriptorProto& from) { CopyFrom(from); return *this; @@ -9584,9 +9359,9 @@ class PROTOBUF_EXPORT EnumDescriptorProto final : inline EnumDescriptorProto& operator=(EnumDescriptorProto&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -9618,22 +9393,17 @@ class PROTOBUF_EXPORT EnumDescriptorProto final : } static inline const EnumDescriptorProto* internal_default_instance() { return reinterpret_cast( - &_EnumDescriptorProto_default_instance_); - } - static constexpr int kIndexInFileMessages = - 10; - - friend void swap(EnumDescriptorProto& a, EnumDescriptorProto& b) { - a.Swap(&b); + &_EnumDescriptorProto_default_instance_); } + static constexpr int kIndexInFileMessages = 10; + friend void swap(EnumDescriptorProto& a, EnumDescriptorProto& b) { a.Swap(&b); } inline void Swap(EnumDescriptorProto* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -9648,16 +9418,18 @@ class PROTOBUF_EXPORT EnumDescriptorProto final : // implements Message ---------------------------------------------- EnumDescriptorProto* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const EnumDescriptorProto& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const EnumDescriptorProto& from) { - EnumDescriptorProto::MergeImpl(*this, from); - } + void MergeFrom(const EnumDescriptorProto& from) { EnumDescriptorProto::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -9665,34 +9437,34 @@ class PROTOBUF_EXPORT EnumDescriptorProto final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(EnumDescriptorProto* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.EnumDescriptorProto"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.EnumDescriptorProto"; } + + protected: explicit EnumDescriptorProto(::google::protobuf::Arena* arena); EnumDescriptorProto(::google::protobuf::Arena* arena, const EnumDescriptorProto& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + EnumDescriptorProto(::google::protobuf::Arena* arena, EnumDescriptorProto&& from) noexcept + : EnumDescriptorProto(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- - using EnumReservedRange = EnumDescriptorProto_EnumReservedRange; // accessors ------------------------------------------------------- - enum : int { kValueFieldNumber = 2, kReservedRangeFieldNumber = 4, @@ -9708,16 +9480,15 @@ class PROTOBUF_EXPORT EnumDescriptorProto final : public: void clear_value() ; ::google::protobuf::EnumValueDescriptorProto* mutable_value(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >* - mutable_value(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumValueDescriptorProto>* mutable_value(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumValueDescriptorProto>& _internal_value() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumValueDescriptorProto>* _internal_mutable_value(); public: const ::google::protobuf::EnumValueDescriptorProto& value(int index) const; ::google::protobuf::EnumValueDescriptorProto* add_value(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >& - value() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumValueDescriptorProto>& value() const; // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; int reserved_range_size() const; private: @@ -9726,16 +9497,15 @@ class PROTOBUF_EXPORT EnumDescriptorProto final : public: void clear_reserved_range() ; ::google::protobuf::EnumDescriptorProto_EnumReservedRange* mutable_reserved_range(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto_EnumReservedRange >* - mutable_reserved_range(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto_EnumReservedRange>* mutable_reserved_range(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto_EnumReservedRange>& _internal_reserved_range() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto_EnumReservedRange>* _internal_mutable_reserved_range(); public: const ::google::protobuf::EnumDescriptorProto_EnumReservedRange& reserved_range(int index) const; ::google::protobuf::EnumDescriptorProto_EnumReservedRange* add_reserved_range(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto_EnumReservedRange >& - reserved_range() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto_EnumReservedRange>& reserved_range() const; // repeated string reserved_name = 5; int reserved_name_size() const; private: @@ -9799,7 +9569,6 @@ class PROTOBUF_EXPORT EnumDescriptorProto final : // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 3, 5, 3, @@ -9811,14 +9580,13 @@ class PROTOBUF_EXPORT EnumDescriptorProto final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_; @@ -9830,23 +9598,21 @@ class PROTOBUF_EXPORT EnumDescriptorProto final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT DescriptorProto final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto) */ { +class PROTOBUF_EXPORT DescriptorProto final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.DescriptorProto) */ { public: inline DescriptorProto() : DescriptorProto(nullptr) {} ~DescriptorProto() override; - template - explicit PROTOBUF_CONSTEXPR DescriptorProto(::google::protobuf::internal::ConstantInitialized); - - inline DescriptorProto(const DescriptorProto& from) - : DescriptorProto(nullptr, from) {} - DescriptorProto(DescriptorProto&& from) noexcept - : DescriptorProto() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR DescriptorProto( + ::google::protobuf::internal::ConstantInitialized); + inline DescriptorProto(const DescriptorProto& from) : DescriptorProto(nullptr, from) {} + inline DescriptorProto(DescriptorProto&& from) noexcept + : DescriptorProto(nullptr, std::move(from)) {} inline DescriptorProto& operator=(const DescriptorProto& from) { CopyFrom(from); return *this; @@ -9854,9 +9620,9 @@ class PROTOBUF_EXPORT DescriptorProto final : inline DescriptorProto& operator=(DescriptorProto&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -9888,22 +9654,17 @@ class PROTOBUF_EXPORT DescriptorProto final : } static inline const DescriptorProto* internal_default_instance() { return reinterpret_cast( - &_DescriptorProto_default_instance_); - } - static constexpr int kIndexInFileMessages = - 4; - - friend void swap(DescriptorProto& a, DescriptorProto& b) { - a.Swap(&b); + &_DescriptorProto_default_instance_); } + static constexpr int kIndexInFileMessages = 4; + friend void swap(DescriptorProto& a, DescriptorProto& b) { a.Swap(&b); } inline void Swap(DescriptorProto* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -9918,16 +9679,18 @@ class PROTOBUF_EXPORT DescriptorProto final : // implements Message ---------------------------------------------- DescriptorProto* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const DescriptorProto& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const DescriptorProto& from) { - DescriptorProto::MergeImpl(*this, from); - } + void MergeFrom(const DescriptorProto& from) { DescriptorProto::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -9935,35 +9698,35 @@ class PROTOBUF_EXPORT DescriptorProto final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(DescriptorProto* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.DescriptorProto"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.DescriptorProto"; } + + protected: explicit DescriptorProto(::google::protobuf::Arena* arena); DescriptorProto(::google::protobuf::Arena* arena, const DescriptorProto& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + DescriptorProto(::google::protobuf::Arena* arena, DescriptorProto&& from) noexcept + : DescriptorProto(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- - using ExtensionRange = DescriptorProto_ExtensionRange; using ReservedRange = DescriptorProto_ReservedRange; // accessors ------------------------------------------------------- - enum : int { kFieldFieldNumber = 2, kNestedTypeFieldNumber = 3, @@ -9984,16 +9747,15 @@ class PROTOBUF_EXPORT DescriptorProto final : public: void clear_field() ; ::google::protobuf::FieldDescriptorProto* mutable_field(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* - mutable_field(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>* mutable_field(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>& _internal_field() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>* _internal_mutable_field(); public: const ::google::protobuf::FieldDescriptorProto& field(int index) const; ::google::protobuf::FieldDescriptorProto* add_field(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& - field() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>& field() const; // repeated .google.protobuf.DescriptorProto nested_type = 3; int nested_type_size() const; private: @@ -10002,16 +9764,15 @@ class PROTOBUF_EXPORT DescriptorProto final : public: void clear_nested_type() ; ::google::protobuf::DescriptorProto* mutable_nested_type(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* - mutable_nested_type(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>* mutable_nested_type(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>& _internal_nested_type() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>* _internal_mutable_nested_type(); public: const ::google::protobuf::DescriptorProto& nested_type(int index) const; ::google::protobuf::DescriptorProto* add_nested_type(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& - nested_type() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>& nested_type() const; // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; int enum_type_size() const; private: @@ -10020,16 +9781,15 @@ class PROTOBUF_EXPORT DescriptorProto final : public: void clear_enum_type() ; ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* - mutable_enum_type(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>* mutable_enum_type(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>& _internal_enum_type() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>* _internal_mutable_enum_type(); public: const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const; ::google::protobuf::EnumDescriptorProto* add_enum_type(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& - enum_type() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>& enum_type() const; // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; int extension_range_size() const; private: @@ -10038,16 +9798,15 @@ class PROTOBUF_EXPORT DescriptorProto final : public: void clear_extension_range() ; ::google::protobuf::DescriptorProto_ExtensionRange* mutable_extension_range(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >* - mutable_extension_range(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ExtensionRange>* mutable_extension_range(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ExtensionRange>& _internal_extension_range() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ExtensionRange>* _internal_mutable_extension_range(); public: const ::google::protobuf::DescriptorProto_ExtensionRange& extension_range(int index) const; ::google::protobuf::DescriptorProto_ExtensionRange* add_extension_range(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >& - extension_range() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ExtensionRange>& extension_range() const; // repeated .google.protobuf.FieldDescriptorProto extension = 6; int extension_size() const; private: @@ -10056,16 +9815,15 @@ class PROTOBUF_EXPORT DescriptorProto final : public: void clear_extension() ; ::google::protobuf::FieldDescriptorProto* mutable_extension(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* - mutable_extension(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>* mutable_extension(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>& _internal_extension() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>* _internal_mutable_extension(); public: const ::google::protobuf::FieldDescriptorProto& extension(int index) const; ::google::protobuf::FieldDescriptorProto* add_extension(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& - extension() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>& extension() const; // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; int oneof_decl_size() const; private: @@ -10074,16 +9832,15 @@ class PROTOBUF_EXPORT DescriptorProto final : public: void clear_oneof_decl() ; ::google::protobuf::OneofDescriptorProto* mutable_oneof_decl(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >* - mutable_oneof_decl(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::OneofDescriptorProto>* mutable_oneof_decl(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::OneofDescriptorProto>& _internal_oneof_decl() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::OneofDescriptorProto>* _internal_mutable_oneof_decl(); public: const ::google::protobuf::OneofDescriptorProto& oneof_decl(int index) const; ::google::protobuf::OneofDescriptorProto* add_oneof_decl(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >& - oneof_decl() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::OneofDescriptorProto>& oneof_decl() const; // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; int reserved_range_size() const; private: @@ -10092,16 +9849,15 @@ class PROTOBUF_EXPORT DescriptorProto final : public: void clear_reserved_range() ; ::google::protobuf::DescriptorProto_ReservedRange* mutable_reserved_range(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >* - mutable_reserved_range(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ReservedRange>* mutable_reserved_range(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ReservedRange>& _internal_reserved_range() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ReservedRange>* _internal_mutable_reserved_range(); public: const ::google::protobuf::DescriptorProto_ReservedRange& reserved_range(int index) const; ::google::protobuf::DescriptorProto_ReservedRange* add_reserved_range(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >& - reserved_range() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ReservedRange>& reserved_range() const; // repeated string reserved_name = 10; int reserved_name_size() const; private: @@ -10165,7 +9921,6 @@ class PROTOBUF_EXPORT DescriptorProto final : // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 4, 10, 8, @@ -10177,14 +9932,13 @@ class PROTOBUF_EXPORT DescriptorProto final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > field_; @@ -10201,23 +9955,21 @@ class PROTOBUF_EXPORT DescriptorProto final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT FileDescriptorProto final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorProto) */ { +class PROTOBUF_EXPORT FileDescriptorProto final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorProto) */ { public: inline FileDescriptorProto() : FileDescriptorProto(nullptr) {} ~FileDescriptorProto() override; - template - explicit PROTOBUF_CONSTEXPR FileDescriptorProto(::google::protobuf::internal::ConstantInitialized); - - inline FileDescriptorProto(const FileDescriptorProto& from) - : FileDescriptorProto(nullptr, from) {} - FileDescriptorProto(FileDescriptorProto&& from) noexcept - : FileDescriptorProto() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR FileDescriptorProto( + ::google::protobuf::internal::ConstantInitialized); + inline FileDescriptorProto(const FileDescriptorProto& from) : FileDescriptorProto(nullptr, from) {} + inline FileDescriptorProto(FileDescriptorProto&& from) noexcept + : FileDescriptorProto(nullptr, std::move(from)) {} inline FileDescriptorProto& operator=(const FileDescriptorProto& from) { CopyFrom(from); return *this; @@ -10225,9 +9977,9 @@ class PROTOBUF_EXPORT FileDescriptorProto final : inline FileDescriptorProto& operator=(FileDescriptorProto&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -10259,22 +10011,17 @@ class PROTOBUF_EXPORT FileDescriptorProto final : } static inline const FileDescriptorProto* internal_default_instance() { return reinterpret_cast( - &_FileDescriptorProto_default_instance_); - } - static constexpr int kIndexInFileMessages = - 1; - - friend void swap(FileDescriptorProto& a, FileDescriptorProto& b) { - a.Swap(&b); + &_FileDescriptorProto_default_instance_); } + static constexpr int kIndexInFileMessages = 1; + friend void swap(FileDescriptorProto& a, FileDescriptorProto& b) { a.Swap(&b); } inline void Swap(FileDescriptorProto* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -10289,16 +10036,18 @@ class PROTOBUF_EXPORT FileDescriptorProto final : // implements Message ---------------------------------------------- FileDescriptorProto* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const FileDescriptorProto& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const FileDescriptorProto& from) { - FileDescriptorProto::MergeImpl(*this, from); - } + void MergeFrom(const FileDescriptorProto& from) { FileDescriptorProto::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -10306,32 +10055,33 @@ class PROTOBUF_EXPORT FileDescriptorProto final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(FileDescriptorProto* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.FileDescriptorProto"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.FileDescriptorProto"; } + + protected: explicit FileDescriptorProto(::google::protobuf::Arena* arena); FileDescriptorProto(::google::protobuf::Arena* arena, const FileDescriptorProto& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + FileDescriptorProto(::google::protobuf::Arena* arena, FileDescriptorProto&& from) noexcept + : FileDescriptorProto(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kDependencyFieldNumber = 3, kMessageTypeFieldNumber = 4, @@ -10383,16 +10133,15 @@ class PROTOBUF_EXPORT FileDescriptorProto final : public: void clear_message_type() ; ::google::protobuf::DescriptorProto* mutable_message_type(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >* - mutable_message_type(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>* mutable_message_type(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>& _internal_message_type() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>* _internal_mutable_message_type(); public: const ::google::protobuf::DescriptorProto& message_type(int index) const; ::google::protobuf::DescriptorProto* add_message_type(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >& - message_type() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>& message_type() const; // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; int enum_type_size() const; private: @@ -10401,16 +10150,15 @@ class PROTOBUF_EXPORT FileDescriptorProto final : public: void clear_enum_type() ; ::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >* - mutable_enum_type(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>* mutable_enum_type(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>& _internal_enum_type() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>* _internal_mutable_enum_type(); public: const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const; ::google::protobuf::EnumDescriptorProto* add_enum_type(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >& - enum_type() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>& enum_type() const; // repeated .google.protobuf.ServiceDescriptorProto service = 6; int service_size() const; private: @@ -10419,16 +10167,15 @@ class PROTOBUF_EXPORT FileDescriptorProto final : public: void clear_service() ; ::google::protobuf::ServiceDescriptorProto* mutable_service(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >* - mutable_service(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::ServiceDescriptorProto>* mutable_service(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::ServiceDescriptorProto>& _internal_service() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::ServiceDescriptorProto>* _internal_mutable_service(); public: const ::google::protobuf::ServiceDescriptorProto& service(int index) const; ::google::protobuf::ServiceDescriptorProto* add_service(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >& - service() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::ServiceDescriptorProto>& service() const; // repeated .google.protobuf.FieldDescriptorProto extension = 7; int extension_size() const; private: @@ -10437,16 +10184,15 @@ class PROTOBUF_EXPORT FileDescriptorProto final : public: void clear_extension() ; ::google::protobuf::FieldDescriptorProto* mutable_extension(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* - mutable_extension(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>* mutable_extension(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>& _internal_extension() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>* _internal_mutable_extension(); public: const ::google::protobuf::FieldDescriptorProto& extension(int index) const; ::google::protobuf::FieldDescriptorProto* add_extension(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& - extension() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>& extension() const; // repeated int32 public_dependency = 10; int public_dependency_size() const; private: @@ -10578,7 +10324,6 @@ class PROTOBUF_EXPORT FileDescriptorProto final : // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 4, 13, 7, @@ -10590,14 +10335,13 @@ class PROTOBUF_EXPORT FileDescriptorProto final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::HasBits<1> _has_bits_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::google::protobuf::RepeatedPtrField dependency_; @@ -10617,23 +10361,21 @@ class PROTOBUF_EXPORT FileDescriptorProto final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fdescriptor_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT FileDescriptorSet final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorSet) */ { +class PROTOBUF_EXPORT FileDescriptorSet final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.FileDescriptorSet) */ { public: inline FileDescriptorSet() : FileDescriptorSet(nullptr) {} ~FileDescriptorSet() override; - template - explicit PROTOBUF_CONSTEXPR FileDescriptorSet(::google::protobuf::internal::ConstantInitialized); - - inline FileDescriptorSet(const FileDescriptorSet& from) - : FileDescriptorSet(nullptr, from) {} - FileDescriptorSet(FileDescriptorSet&& from) noexcept - : FileDescriptorSet() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR FileDescriptorSet( + ::google::protobuf::internal::ConstantInitialized); + inline FileDescriptorSet(const FileDescriptorSet& from) : FileDescriptorSet(nullptr, from) {} + inline FileDescriptorSet(FileDescriptorSet&& from) noexcept + : FileDescriptorSet(nullptr, std::move(from)) {} inline FileDescriptorSet& operator=(const FileDescriptorSet& from) { CopyFrom(from); return *this; @@ -10641,9 +10383,9 @@ class PROTOBUF_EXPORT FileDescriptorSet final : inline FileDescriptorSet& operator=(FileDescriptorSet&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -10675,22 +10417,17 @@ class PROTOBUF_EXPORT FileDescriptorSet final : } static inline const FileDescriptorSet* internal_default_instance() { return reinterpret_cast( - &_FileDescriptorSet_default_instance_); - } - static constexpr int kIndexInFileMessages = - 0; - - friend void swap(FileDescriptorSet& a, FileDescriptorSet& b) { - a.Swap(&b); + &_FileDescriptorSet_default_instance_); } + static constexpr int kIndexInFileMessages = 0; + friend void swap(FileDescriptorSet& a, FileDescriptorSet& b) { a.Swap(&b); } inline void Swap(FileDescriptorSet* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -10705,16 +10442,18 @@ class PROTOBUF_EXPORT FileDescriptorSet final : // implements Message ---------------------------------------------- FileDescriptorSet* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const FileDescriptorSet& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const FileDescriptorSet& from) { - FileDescriptorSet::MergeImpl(*this, from); - } + void MergeFrom(const FileDescriptorSet& from) { FileDescriptorSet::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -10722,32 +10461,33 @@ class PROTOBUF_EXPORT FileDescriptorSet final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(FileDescriptorSet* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.FileDescriptorSet"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.FileDescriptorSet"; } + + protected: explicit FileDescriptorSet(::google::protobuf::Arena* arena); FileDescriptorSet(::google::protobuf::Arena* arena, const FileDescriptorSet& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + FileDescriptorSet(::google::protobuf::Arena* arena, FileDescriptorSet&& from) noexcept + : FileDescriptorSet(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kFileFieldNumber = 1, }; @@ -10759,20 +10499,18 @@ class PROTOBUF_EXPORT FileDescriptorSet final : public: void clear_file() ; ::google::protobuf::FileDescriptorProto* mutable_file(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >* - mutable_file(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* mutable_file(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& _internal_file() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* _internal_mutable_file(); public: const ::google::protobuf::FileDescriptorProto& file(int index) const; ::google::protobuf::FileDescriptorProto* add_file(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >& - file() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& file() const; // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 0, 1, 1, @@ -10784,14 +10522,13 @@ class PROTOBUF_EXPORT FileDescriptorSet final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_; mutable ::google::protobuf::internal::CachedSize _cached_size_; PROTOBUF_TSAN_DECLARE_MEMBER @@ -11461,14 +11198,14 @@ inline ::google::protobuf::FileOptions* FileDescriptorProto::unsafe_arena_releas } inline ::google::protobuf::FileOptions* FileDescriptorProto::_internal_mutable_options() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000008u; if (_impl_.options_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::FileOptions>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FileOptions>(GetArena()); _impl_.options_ = reinterpret_cast<::google::protobuf::FileOptions*>(p); } return _impl_.options_; } inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000008u; ::google::protobuf::FileOptions* _msg = _internal_mutable_options(); // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.options) return _msg; @@ -11557,14 +11294,14 @@ inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::unsafe_arena_rel } inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::_internal_mutable_source_code_info() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000010u; if (_impl_.source_code_info_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::SourceCodeInfo>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::SourceCodeInfo>(GetArena()); _impl_.source_code_info_ = reinterpret_cast<::google::protobuf::SourceCodeInfo*>(p); } return _impl_.source_code_info_; } inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000010u; ::google::protobuf::SourceCodeInfo* _msg = _internal_mutable_source_code_info(); // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.source_code_info) return _msg; @@ -11677,6 +11414,7 @@ inline ::google::protobuf::Edition FileDescriptorProto::edition() const { } inline void FileDescriptorProto::set_edition(::google::protobuf::Edition value) { _internal_set_edition(value); + _impl_._has_bits_[0] |= 0x00000020u; // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.edition) } inline ::google::protobuf::Edition FileDescriptorProto::_internal_edition() const { @@ -11686,7 +11424,6 @@ inline ::google::protobuf::Edition FileDescriptorProto::_internal_edition() cons inline void FileDescriptorProto::_internal_set_edition(::google::protobuf::Edition value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::Edition_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000020u; _impl_.edition_ = value; } @@ -11710,6 +11447,7 @@ inline ::int32_t DescriptorProto_ExtensionRange::start() const { } inline void DescriptorProto_ExtensionRange::set_start(::int32_t value) { _internal_set_start(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.start) } inline ::int32_t DescriptorProto_ExtensionRange::_internal_start() const { @@ -11718,7 +11456,6 @@ inline ::int32_t DescriptorProto_ExtensionRange::_internal_start() const { } inline void DescriptorProto_ExtensionRange::_internal_set_start(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.start_ = value; } @@ -11738,6 +11475,7 @@ inline ::int32_t DescriptorProto_ExtensionRange::end() const { } inline void DescriptorProto_ExtensionRange::set_end(::int32_t value) { _internal_set_end(value); + _impl_._has_bits_[0] |= 0x00000004u; // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.end) } inline ::int32_t DescriptorProto_ExtensionRange::_internal_end() const { @@ -11746,7 +11484,6 @@ inline ::int32_t DescriptorProto_ExtensionRange::_internal_end() const { } inline void DescriptorProto_ExtensionRange::_internal_set_end(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000004u; _impl_.end_ = value; } @@ -11813,14 +11550,14 @@ inline ::google::protobuf::ExtensionRangeOptions* DescriptorProto_ExtensionRange } inline ::google::protobuf::ExtensionRangeOptions* DescriptorProto_ExtensionRange::_internal_mutable_options() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000001u; if (_impl_.options_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::ExtensionRangeOptions>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::ExtensionRangeOptions>(GetArena()); _impl_.options_ = reinterpret_cast<::google::protobuf::ExtensionRangeOptions*>(p); } return _impl_.options_; } inline ::google::protobuf::ExtensionRangeOptions* DescriptorProto_ExtensionRange::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000001u; ::google::protobuf::ExtensionRangeOptions* _msg = _internal_mutable_options(); // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.ExtensionRange.options) return _msg; @@ -11866,6 +11603,7 @@ inline ::int32_t DescriptorProto_ReservedRange::start() const { } inline void DescriptorProto_ReservedRange::set_start(::int32_t value) { _internal_set_start(value); + _impl_._has_bits_[0] |= 0x00000001u; // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ReservedRange.start) } inline ::int32_t DescriptorProto_ReservedRange::_internal_start() const { @@ -11874,7 +11612,6 @@ inline ::int32_t DescriptorProto_ReservedRange::_internal_start() const { } inline void DescriptorProto_ReservedRange::_internal_set_start(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000001u; _impl_.start_ = value; } @@ -11894,6 +11631,7 @@ inline ::int32_t DescriptorProto_ReservedRange::end() const { } inline void DescriptorProto_ReservedRange::set_end(::int32_t value) { _internal_set_end(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ReservedRange.end) } inline ::int32_t DescriptorProto_ReservedRange::_internal_end() const { @@ -11902,7 +11640,6 @@ inline ::int32_t DescriptorProto_ReservedRange::_internal_end() const { } inline void DescriptorProto_ReservedRange::_internal_set_end(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.end_ = value; } @@ -12338,14 +12075,14 @@ inline ::google::protobuf::MessageOptions* DescriptorProto::unsafe_arena_release } inline ::google::protobuf::MessageOptions* DescriptorProto::_internal_mutable_options() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; if (_impl_.options_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::MessageOptions>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::MessageOptions>(GetArena()); _impl_.options_ = reinterpret_cast<::google::protobuf::MessageOptions*>(p); } return _impl_.options_; } inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000002u; ::google::protobuf::MessageOptions* _msg = _internal_mutable_options(); // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.options) return _msg; @@ -12541,6 +12278,7 @@ inline ::int32_t ExtensionRangeOptions_Declaration::number() const { } inline void ExtensionRangeOptions_Declaration::set_number(::int32_t value) { _internal_set_number(value); + _impl_._has_bits_[0] |= 0x00000004u; // @@protoc_insertion_point(field_set:google.protobuf.ExtensionRangeOptions.Declaration.number) } inline ::int32_t ExtensionRangeOptions_Declaration::_internal_number() const { @@ -12549,7 +12287,6 @@ inline ::int32_t ExtensionRangeOptions_Declaration::_internal_number() const { } inline void ExtensionRangeOptions_Declaration::_internal_set_number(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000004u; _impl_.number_ = value; } @@ -12711,6 +12448,7 @@ inline bool ExtensionRangeOptions_Declaration::reserved() const { } inline void ExtensionRangeOptions_Declaration::set_reserved(bool value) { _internal_set_reserved(value); + _impl_._has_bits_[0] |= 0x00000008u; // @@protoc_insertion_point(field_set:google.protobuf.ExtensionRangeOptions.Declaration.reserved) } inline bool ExtensionRangeOptions_Declaration::_internal_reserved() const { @@ -12719,7 +12457,6 @@ inline bool ExtensionRangeOptions_Declaration::_internal_reserved() const { } inline void ExtensionRangeOptions_Declaration::_internal_set_reserved(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000008u; _impl_.reserved_ = value; } @@ -12739,6 +12476,7 @@ inline bool ExtensionRangeOptions_Declaration::repeated() const { } inline void ExtensionRangeOptions_Declaration::set_repeated(bool value) { _internal_set_repeated(value); + _impl_._has_bits_[0] |= 0x00000010u; // @@protoc_insertion_point(field_set:google.protobuf.ExtensionRangeOptions.Declaration.repeated) } inline bool ExtensionRangeOptions_Declaration::_internal_repeated() const { @@ -12747,7 +12485,6 @@ inline bool ExtensionRangeOptions_Declaration::_internal_repeated() const { } inline void ExtensionRangeOptions_Declaration::_internal_set_repeated(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000010u; _impl_.repeated_ = value; } @@ -12916,14 +12653,14 @@ inline ::google::protobuf::FeatureSet* ExtensionRangeOptions::unsafe_arena_relea } inline ::google::protobuf::FeatureSet* ExtensionRangeOptions::_internal_mutable_features() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000001u; if (_impl_.features_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::FeatureSet>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena()); _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p); } return _impl_.features_; } inline ::google::protobuf::FeatureSet* ExtensionRangeOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000001u; ::google::protobuf::FeatureSet* _msg = _internal_mutable_features(); // @@protoc_insertion_point(field_mutable:google.protobuf.ExtensionRangeOptions.features) return _msg; @@ -12949,7 +12686,7 @@ inline void ExtensionRangeOptions::set_allocated_features(::google::protobuf::Fe // @@protoc_insertion_point(field_set_allocated:google.protobuf.ExtensionRangeOptions.features) } -// optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED]; +// optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED, retention = RETENTION_SOURCE]; inline bool ExtensionRangeOptions::has_verification() const { bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0; return value; @@ -12965,6 +12702,7 @@ inline ::google::protobuf::ExtensionRangeOptions_VerificationState ExtensionRang } inline void ExtensionRangeOptions::set_verification(::google::protobuf::ExtensionRangeOptions_VerificationState value) { _internal_set_verification(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.ExtensionRangeOptions.verification) } inline ::google::protobuf::ExtensionRangeOptions_VerificationState ExtensionRangeOptions::_internal_verification() const { @@ -12974,7 +12712,6 @@ inline ::google::protobuf::ExtensionRangeOptions_VerificationState ExtensionRang inline void ExtensionRangeOptions::_internal_set_verification(::google::protobuf::ExtensionRangeOptions_VerificationState value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::ExtensionRangeOptions_VerificationState_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.verification_ = value; } @@ -13069,6 +12806,7 @@ inline ::int32_t FieldDescriptorProto::number() const { } inline void FieldDescriptorProto::set_number(::int32_t value) { _internal_set_number(value); + _impl_._has_bits_[0] |= 0x00000040u; // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.number) } inline ::int32_t FieldDescriptorProto::_internal_number() const { @@ -13077,7 +12815,6 @@ inline ::int32_t FieldDescriptorProto::_internal_number() const { } inline void FieldDescriptorProto::_internal_set_number(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000040u; _impl_.number_ = value; } @@ -13097,6 +12834,7 @@ inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::labe } inline void FieldDescriptorProto::set_label(::google::protobuf::FieldDescriptorProto_Label value) { _internal_set_label(value); + _impl_._has_bits_[0] |= 0x00000200u; // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.label) } inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::_internal_label() const { @@ -13106,7 +12844,6 @@ inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::_int inline void FieldDescriptorProto::_internal_set_label(::google::protobuf::FieldDescriptorProto_Label value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FieldDescriptorProto_Label_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000200u; _impl_.label_ = value; } @@ -13126,6 +12863,7 @@ inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::type( } inline void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Type value) { _internal_set_type(value); + _impl_._has_bits_[0] |= 0x00000400u; // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type) } inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::_internal_type() const { @@ -13135,7 +12873,6 @@ inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::_inte inline void FieldDescriptorProto::_internal_set_type(::google::protobuf::FieldDescriptorProto_Type value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FieldDescriptorProto_Type_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000400u; _impl_.type_ = value; } @@ -13368,6 +13105,7 @@ inline ::int32_t FieldDescriptorProto::oneof_index() const { } inline void FieldDescriptorProto::set_oneof_index(::int32_t value) { _internal_set_oneof_index(value); + _impl_._has_bits_[0] |= 0x00000080u; // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.oneof_index) } inline ::int32_t FieldDescriptorProto::_internal_oneof_index() const { @@ -13376,7 +13114,6 @@ inline ::int32_t FieldDescriptorProto::_internal_oneof_index() const { } inline void FieldDescriptorProto::_internal_set_oneof_index(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000080u; _impl_.oneof_index_ = value; } @@ -13514,14 +13251,14 @@ inline ::google::protobuf::FieldOptions* FieldDescriptorProto::unsafe_arena_rele } inline ::google::protobuf::FieldOptions* FieldDescriptorProto::_internal_mutable_options() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000020u; if (_impl_.options_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::FieldOptions>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FieldOptions>(GetArena()); _impl_.options_ = reinterpret_cast<::google::protobuf::FieldOptions*>(p); } return _impl_.options_; } inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000020u; ::google::protobuf::FieldOptions* _msg = _internal_mutable_options(); // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.options) return _msg; @@ -13563,6 +13300,7 @@ inline bool FieldDescriptorProto::proto3_optional() const { } inline void FieldDescriptorProto::set_proto3_optional(bool value) { _internal_set_proto3_optional(value); + _impl_._has_bits_[0] |= 0x00000100u; // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.proto3_optional) } inline bool FieldDescriptorProto::_internal_proto3_optional() const { @@ -13571,7 +13309,6 @@ inline bool FieldDescriptorProto::_internal_proto3_optional() const { } inline void FieldDescriptorProto::_internal_set_proto3_optional(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000100u; _impl_.proto3_optional_ = value; } @@ -13713,14 +13450,14 @@ inline ::google::protobuf::OneofOptions* OneofDescriptorProto::unsafe_arena_rele } inline ::google::protobuf::OneofOptions* OneofDescriptorProto::_internal_mutable_options() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; if (_impl_.options_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::OneofOptions>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::OneofOptions>(GetArena()); _impl_.options_ = reinterpret_cast<::google::protobuf::OneofOptions*>(p); } return _impl_.options_; } inline ::google::protobuf::OneofOptions* OneofDescriptorProto::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000002u; ::google::protobuf::OneofOptions* _msg = _internal_mutable_options(); // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.options) return _msg; @@ -13766,6 +13503,7 @@ inline ::int32_t EnumDescriptorProto_EnumReservedRange::start() const { } inline void EnumDescriptorProto_EnumReservedRange::set_start(::int32_t value) { _internal_set_start(value); + _impl_._has_bits_[0] |= 0x00000001u; // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.EnumReservedRange.start) } inline ::int32_t EnumDescriptorProto_EnumReservedRange::_internal_start() const { @@ -13774,7 +13512,6 @@ inline ::int32_t EnumDescriptorProto_EnumReservedRange::_internal_start() const } inline void EnumDescriptorProto_EnumReservedRange::_internal_set_start(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000001u; _impl_.start_ = value; } @@ -13794,6 +13531,7 @@ inline ::int32_t EnumDescriptorProto_EnumReservedRange::end() const { } inline void EnumDescriptorProto_EnumReservedRange::set_end(::int32_t value) { _internal_set_end(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.EnumReservedRange.end) } inline ::int32_t EnumDescriptorProto_EnumReservedRange::_internal_end() const { @@ -13802,7 +13540,6 @@ inline ::int32_t EnumDescriptorProto_EnumReservedRange::_internal_end() const { } inline void EnumDescriptorProto_EnumReservedRange::_internal_set_end(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.end_ = value; } @@ -13993,14 +13730,14 @@ inline ::google::protobuf::EnumOptions* EnumDescriptorProto::unsafe_arena_releas } inline ::google::protobuf::EnumOptions* EnumDescriptorProto::_internal_mutable_options() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; if (_impl_.options_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::EnumOptions>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::EnumOptions>(GetArena()); _impl_.options_ = reinterpret_cast<::google::protobuf::EnumOptions*>(p); } return _impl_.options_; } inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000002u; ::google::protobuf::EnumOptions* _msg = _internal_mutable_options(); // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.options) return _msg; @@ -14267,6 +14004,7 @@ inline ::int32_t EnumValueDescriptorProto::number() const { } inline void EnumValueDescriptorProto::set_number(::int32_t value) { _internal_set_number(value); + _impl_._has_bits_[0] |= 0x00000004u; // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.number) } inline ::int32_t EnumValueDescriptorProto::_internal_number() const { @@ -14275,7 +14013,6 @@ inline ::int32_t EnumValueDescriptorProto::_internal_number() const { } inline void EnumValueDescriptorProto::_internal_set_number(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000004u; _impl_.number_ = value; } @@ -14342,14 +14079,14 @@ inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::unsafe_ar } inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::_internal_mutable_options() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; if (_impl_.options_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::EnumValueOptions>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::EnumValueOptions>(GetArena()); _impl_.options_ = reinterpret_cast<::google::protobuf::EnumValueOptions*>(p); } return _impl_.options_; } inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000002u; ::google::protobuf::EnumValueOptions* _msg = _internal_mutable_options(); // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.options) return _msg; @@ -14562,14 +14299,14 @@ inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::unsafe_arena_ } inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::_internal_mutable_options() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; if (_impl_.options_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::ServiceOptions>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::ServiceOptions>(GetArena()); _impl_.options_ = reinterpret_cast<::google::protobuf::ServiceOptions*>(p); } return _impl_.options_; } inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000002u; ::google::protobuf::ServiceOptions* _msg = _internal_mutable_options(); // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.options) return _msg; @@ -14875,14 +14612,14 @@ inline ::google::protobuf::MethodOptions* MethodDescriptorProto::unsafe_arena_re } inline ::google::protobuf::MethodOptions* MethodDescriptorProto::_internal_mutable_options() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000008u; if (_impl_.options_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::MethodOptions>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::MethodOptions>(GetArena()); _impl_.options_ = reinterpret_cast<::google::protobuf::MethodOptions*>(p); } return _impl_.options_; } inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000008u; ::google::protobuf::MethodOptions* _msg = _internal_mutable_options(); // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.options) return _msg; @@ -14924,6 +14661,7 @@ inline bool MethodDescriptorProto::client_streaming() const { } inline void MethodDescriptorProto::set_client_streaming(bool value) { _internal_set_client_streaming(value); + _impl_._has_bits_[0] |= 0x00000010u; // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.client_streaming) } inline bool MethodDescriptorProto::_internal_client_streaming() const { @@ -14932,7 +14670,6 @@ inline bool MethodDescriptorProto::_internal_client_streaming() const { } inline void MethodDescriptorProto::_internal_set_client_streaming(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000010u; _impl_.client_streaming_ = value; } @@ -14952,6 +14689,7 @@ inline bool MethodDescriptorProto::server_streaming() const { } inline void MethodDescriptorProto::set_server_streaming(bool value) { _internal_set_server_streaming(value); + _impl_._has_bits_[0] |= 0x00000020u; // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.server_streaming) } inline bool MethodDescriptorProto::_internal_server_streaming() const { @@ -14960,7 +14698,6 @@ inline bool MethodDescriptorProto::_internal_server_streaming() const { } inline void MethodDescriptorProto::_internal_set_server_streaming(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000020u; _impl_.server_streaming_ = value; } @@ -15126,6 +14863,7 @@ inline bool FileOptions::java_multiple_files() const { } inline void FileOptions::set_java_multiple_files(bool value) { _internal_set_java_multiple_files(value); + _impl_._has_bits_[0] |= 0x00000800u; // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_multiple_files) } inline bool FileOptions::_internal_java_multiple_files() const { @@ -15134,7 +14872,6 @@ inline bool FileOptions::_internal_java_multiple_files() const { } inline void FileOptions::_internal_set_java_multiple_files(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000800u; _impl_.java_multiple_files_ = value; } @@ -15154,6 +14891,7 @@ inline bool FileOptions::java_generate_equals_and_hash() const { } inline void FileOptions::set_java_generate_equals_and_hash(bool value) { _internal_set_java_generate_equals_and_hash(value); + _impl_._has_bits_[0] |= 0x00001000u; // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generate_equals_and_hash) } inline bool FileOptions::_internal_java_generate_equals_and_hash() const { @@ -15162,7 +14900,6 @@ inline bool FileOptions::_internal_java_generate_equals_and_hash() const { } inline void FileOptions::_internal_set_java_generate_equals_and_hash(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00001000u; _impl_.java_generate_equals_and_hash_ = value; } @@ -15182,6 +14919,7 @@ inline bool FileOptions::java_string_check_utf8() const { } inline void FileOptions::set_java_string_check_utf8(bool value) { _internal_set_java_string_check_utf8(value); + _impl_._has_bits_[0] |= 0x00002000u; // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_string_check_utf8) } inline bool FileOptions::_internal_java_string_check_utf8() const { @@ -15190,7 +14928,6 @@ inline bool FileOptions::_internal_java_string_check_utf8() const { } inline void FileOptions::_internal_set_java_string_check_utf8(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00002000u; _impl_.java_string_check_utf8_ = value; } @@ -15210,6 +14947,7 @@ inline ::google::protobuf::FileOptions_OptimizeMode FileOptions::optimize_for() } inline void FileOptions::set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value) { _internal_set_optimize_for(value); + _impl_._has_bits_[0] |= 0x00080000u; // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.optimize_for) } inline ::google::protobuf::FileOptions_OptimizeMode FileOptions::_internal_optimize_for() const { @@ -15219,7 +14957,6 @@ inline ::google::protobuf::FileOptions_OptimizeMode FileOptions::_internal_optim inline void FileOptions::_internal_set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FileOptions_OptimizeMode_IsValid(value)); - _impl_._has_bits_[0] |= 0x00080000u; _impl_.optimize_for_ = value; } @@ -15310,6 +15047,7 @@ inline bool FileOptions::cc_generic_services() const { } inline void FileOptions::set_cc_generic_services(bool value) { _internal_set_cc_generic_services(value); + _impl_._has_bits_[0] |= 0x00004000u; // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_generic_services) } inline bool FileOptions::_internal_cc_generic_services() const { @@ -15318,7 +15056,6 @@ inline bool FileOptions::_internal_cc_generic_services() const { } inline void FileOptions::_internal_set_cc_generic_services(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00004000u; _impl_.cc_generic_services_ = value; } @@ -15338,6 +15075,7 @@ inline bool FileOptions::java_generic_services() const { } inline void FileOptions::set_java_generic_services(bool value) { _internal_set_java_generic_services(value); + _impl_._has_bits_[0] |= 0x00008000u; // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generic_services) } inline bool FileOptions::_internal_java_generic_services() const { @@ -15346,7 +15084,6 @@ inline bool FileOptions::_internal_java_generic_services() const { } inline void FileOptions::_internal_set_java_generic_services(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00008000u; _impl_.java_generic_services_ = value; } @@ -15366,6 +15103,7 @@ inline bool FileOptions::py_generic_services() const { } inline void FileOptions::set_py_generic_services(bool value) { _internal_set_py_generic_services(value); + _impl_._has_bits_[0] |= 0x00010000u; // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.py_generic_services) } inline bool FileOptions::_internal_py_generic_services() const { @@ -15374,7 +15112,6 @@ inline bool FileOptions::_internal_py_generic_services() const { } inline void FileOptions::_internal_set_py_generic_services(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00010000u; _impl_.py_generic_services_ = value; } @@ -15394,6 +15131,7 @@ inline bool FileOptions::php_generic_services() const { } inline void FileOptions::set_php_generic_services(bool value) { _internal_set_php_generic_services(value); + _impl_._has_bits_[0] |= 0x00020000u; // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.php_generic_services) } inline bool FileOptions::_internal_php_generic_services() const { @@ -15402,7 +15140,6 @@ inline bool FileOptions::_internal_php_generic_services() const { } inline void FileOptions::_internal_set_php_generic_services(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00020000u; _impl_.php_generic_services_ = value; } @@ -15422,6 +15159,7 @@ inline bool FileOptions::deprecated() const { } inline void FileOptions::set_deprecated(bool value) { _internal_set_deprecated(value); + _impl_._has_bits_[0] |= 0x00040000u; // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.deprecated) } inline bool FileOptions::_internal_deprecated() const { @@ -15430,7 +15168,6 @@ inline bool FileOptions::_internal_deprecated() const { } inline void FileOptions::_internal_set_deprecated(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00040000u; _impl_.deprecated_ = value; } @@ -15450,6 +15187,7 @@ inline bool FileOptions::cc_enable_arenas() const { } inline void FileOptions::set_cc_enable_arenas(bool value) { _internal_set_cc_enable_arenas(value); + _impl_._has_bits_[0] |= 0x00100000u; // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_enable_arenas) } inline bool FileOptions::_internal_cc_enable_arenas() const { @@ -15458,7 +15196,6 @@ inline bool FileOptions::_internal_cc_enable_arenas() const { } inline void FileOptions::_internal_set_cc_enable_arenas(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00100000u; _impl_.cc_enable_arenas_ = value; } @@ -16022,14 +15759,14 @@ inline ::google::protobuf::FeatureSet* FileOptions::unsafe_arena_release_feature } inline ::google::protobuf::FeatureSet* FileOptions::_internal_mutable_features() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000400u; if (_impl_.features_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::FeatureSet>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena()); _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p); } return _impl_.features_; } inline ::google::protobuf::FeatureSet* FileOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000400u; ::google::protobuf::FeatureSet* _msg = _internal_mutable_features(); // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.features) return _msg; @@ -16124,6 +15861,7 @@ inline bool MessageOptions::message_set_wire_format() const { } inline void MessageOptions::set_message_set_wire_format(bool value) { _internal_set_message_set_wire_format(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.message_set_wire_format) } inline bool MessageOptions::_internal_message_set_wire_format() const { @@ -16132,7 +15870,6 @@ inline bool MessageOptions::_internal_message_set_wire_format() const { } inline void MessageOptions::_internal_set_message_set_wire_format(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.message_set_wire_format_ = value; } @@ -16152,6 +15889,7 @@ inline bool MessageOptions::no_standard_descriptor_accessor() const { } inline void MessageOptions::set_no_standard_descriptor_accessor(bool value) { _internal_set_no_standard_descriptor_accessor(value); + _impl_._has_bits_[0] |= 0x00000004u; // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.no_standard_descriptor_accessor) } inline bool MessageOptions::_internal_no_standard_descriptor_accessor() const { @@ -16160,7 +15898,6 @@ inline bool MessageOptions::_internal_no_standard_descriptor_accessor() const { } inline void MessageOptions::_internal_set_no_standard_descriptor_accessor(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000004u; _impl_.no_standard_descriptor_accessor_ = value; } @@ -16180,6 +15917,7 @@ inline bool MessageOptions::deprecated() const { } inline void MessageOptions::set_deprecated(bool value) { _internal_set_deprecated(value); + _impl_._has_bits_[0] |= 0x00000008u; // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.deprecated) } inline bool MessageOptions::_internal_deprecated() const { @@ -16188,7 +15926,6 @@ inline bool MessageOptions::_internal_deprecated() const { } inline void MessageOptions::_internal_set_deprecated(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000008u; _impl_.deprecated_ = value; } @@ -16208,6 +15945,7 @@ inline bool MessageOptions::map_entry() const { } inline void MessageOptions::set_map_entry(bool value) { _internal_set_map_entry(value); + _impl_._has_bits_[0] |= 0x00000010u; // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.map_entry) } inline bool MessageOptions::_internal_map_entry() const { @@ -16216,7 +15954,6 @@ inline bool MessageOptions::_internal_map_entry() const { } inline void MessageOptions::_internal_set_map_entry(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000010u; _impl_.map_entry_ = value; } @@ -16236,6 +15973,7 @@ inline bool MessageOptions::deprecated_legacy_json_field_conflicts() const { } inline void MessageOptions::set_deprecated_legacy_json_field_conflicts(bool value) { _internal_set_deprecated_legacy_json_field_conflicts(value); + _impl_._has_bits_[0] |= 0x00000020u; // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.deprecated_legacy_json_field_conflicts) } inline bool MessageOptions::_internal_deprecated_legacy_json_field_conflicts() const { @@ -16244,7 +15982,6 @@ inline bool MessageOptions::_internal_deprecated_legacy_json_field_conflicts() c } inline void MessageOptions::_internal_set_deprecated_legacy_json_field_conflicts(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000020u; _impl_.deprecated_legacy_json_field_conflicts_ = value; } @@ -16311,14 +16048,14 @@ inline ::google::protobuf::FeatureSet* MessageOptions::unsafe_arena_release_feat } inline ::google::protobuf::FeatureSet* MessageOptions::_internal_mutable_features() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000001u; if (_impl_.features_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::FeatureSet>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena()); _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p); } return _impl_.features_; } inline ::google::protobuf::FeatureSet* MessageOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000001u; ::google::protobuf::FeatureSet* _msg = _internal_mutable_features(); // @@protoc_insertion_point(field_mutable:google.protobuf.MessageOptions.features) return _msg; @@ -16413,6 +16150,7 @@ inline ::google::protobuf::Edition FieldOptions_EditionDefault::edition() const } inline void FieldOptions_EditionDefault::set_edition(::google::protobuf::Edition value) { _internal_set_edition(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.EditionDefault.edition) } inline ::google::protobuf::Edition FieldOptions_EditionDefault::_internal_edition() const { @@ -16422,7 +16160,6 @@ inline ::google::protobuf::Edition FieldOptions_EditionDefault::_internal_editio inline void FieldOptions_EditionDefault::_internal_set_edition(::google::protobuf::Edition value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::Edition_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.edition_ = value; } @@ -16517,6 +16254,7 @@ inline ::google::protobuf::FieldOptions_CType FieldOptions::ctype() const { } inline void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value) { _internal_set_ctype(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.ctype) } inline ::google::protobuf::FieldOptions_CType FieldOptions::_internal_ctype() const { @@ -16526,7 +16264,6 @@ inline ::google::protobuf::FieldOptions_CType FieldOptions::_internal_ctype() co inline void FieldOptions::_internal_set_ctype(::google::protobuf::FieldOptions_CType value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FieldOptions_CType_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.ctype_ = value; } @@ -16546,6 +16283,7 @@ inline bool FieldOptions::packed() const { } inline void FieldOptions::set_packed(bool value) { _internal_set_packed(value); + _impl_._has_bits_[0] |= 0x00000008u; // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.packed) } inline bool FieldOptions::_internal_packed() const { @@ -16554,7 +16292,6 @@ inline bool FieldOptions::_internal_packed() const { } inline void FieldOptions::_internal_set_packed(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000008u; _impl_.packed_ = value; } @@ -16574,6 +16311,7 @@ inline ::google::protobuf::FieldOptions_JSType FieldOptions::jstype() const { } inline void FieldOptions::set_jstype(::google::protobuf::FieldOptions_JSType value) { _internal_set_jstype(value); + _impl_._has_bits_[0] |= 0x00000004u; // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.jstype) } inline ::google::protobuf::FieldOptions_JSType FieldOptions::_internal_jstype() const { @@ -16583,7 +16321,6 @@ inline ::google::protobuf::FieldOptions_JSType FieldOptions::_internal_jstype() inline void FieldOptions::_internal_set_jstype(::google::protobuf::FieldOptions_JSType value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FieldOptions_JSType_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000004u; _impl_.jstype_ = value; } @@ -16603,6 +16340,7 @@ inline bool FieldOptions::lazy() const { } inline void FieldOptions::set_lazy(bool value) { _internal_set_lazy(value); + _impl_._has_bits_[0] |= 0x00000010u; // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.lazy) } inline bool FieldOptions::_internal_lazy() const { @@ -16611,7 +16349,6 @@ inline bool FieldOptions::_internal_lazy() const { } inline void FieldOptions::_internal_set_lazy(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000010u; _impl_.lazy_ = value; } @@ -16631,6 +16368,7 @@ inline bool FieldOptions::unverified_lazy() const { } inline void FieldOptions::set_unverified_lazy(bool value) { _internal_set_unverified_lazy(value); + _impl_._has_bits_[0] |= 0x00000020u; // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.unverified_lazy) } inline bool FieldOptions::_internal_unverified_lazy() const { @@ -16639,7 +16377,6 @@ inline bool FieldOptions::_internal_unverified_lazy() const { } inline void FieldOptions::_internal_set_unverified_lazy(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000020u; _impl_.unverified_lazy_ = value; } @@ -16659,6 +16396,7 @@ inline bool FieldOptions::deprecated() const { } inline void FieldOptions::set_deprecated(bool value) { _internal_set_deprecated(value); + _impl_._has_bits_[0] |= 0x00000040u; // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.deprecated) } inline bool FieldOptions::_internal_deprecated() const { @@ -16667,7 +16405,6 @@ inline bool FieldOptions::_internal_deprecated() const { } inline void FieldOptions::_internal_set_deprecated(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000040u; _impl_.deprecated_ = value; } @@ -16687,6 +16424,7 @@ inline bool FieldOptions::weak() const { } inline void FieldOptions::set_weak(bool value) { _internal_set_weak(value); + _impl_._has_bits_[0] |= 0x00000080u; // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.weak) } inline bool FieldOptions::_internal_weak() const { @@ -16695,7 +16433,6 @@ inline bool FieldOptions::_internal_weak() const { } inline void FieldOptions::_internal_set_weak(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000080u; _impl_.weak_ = value; } @@ -16715,6 +16452,7 @@ inline bool FieldOptions::debug_redact() const { } inline void FieldOptions::set_debug_redact(bool value) { _internal_set_debug_redact(value); + _impl_._has_bits_[0] |= 0x00000100u; // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.debug_redact) } inline bool FieldOptions::_internal_debug_redact() const { @@ -16723,7 +16461,6 @@ inline bool FieldOptions::_internal_debug_redact() const { } inline void FieldOptions::_internal_set_debug_redact(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000100u; _impl_.debug_redact_ = value; } @@ -16743,6 +16480,7 @@ inline ::google::protobuf::FieldOptions_OptionRetention FieldOptions::retention( } inline void FieldOptions::set_retention(::google::protobuf::FieldOptions_OptionRetention value) { _internal_set_retention(value); + _impl_._has_bits_[0] |= 0x00000200u; // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.retention) } inline ::google::protobuf::FieldOptions_OptionRetention FieldOptions::_internal_retention() const { @@ -16752,7 +16490,6 @@ inline ::google::protobuf::FieldOptions_OptionRetention FieldOptions::_internal_ inline void FieldOptions::_internal_set_retention(::google::protobuf::FieldOptions_OptionRetention value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FieldOptions_OptionRetention_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000200u; _impl_.retention_ = value; } @@ -16914,14 +16651,14 @@ inline ::google::protobuf::FeatureSet* FieldOptions::unsafe_arena_release_featur } inline ::google::protobuf::FeatureSet* FieldOptions::_internal_mutable_features() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000001u; if (_impl_.features_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::FeatureSet>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena()); _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p); } return _impl_.features_; } inline ::google::protobuf::FeatureSet* FieldOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000001u; ::google::protobuf::FeatureSet* _msg = _internal_mutable_features(); // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.features) return _msg; @@ -17063,14 +16800,14 @@ inline ::google::protobuf::FeatureSet* OneofOptions::unsafe_arena_release_featur } inline ::google::protobuf::FeatureSet* OneofOptions::_internal_mutable_features() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000001u; if (_impl_.features_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::FeatureSet>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena()); _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p); } return _impl_.features_; } inline ::google::protobuf::FeatureSet* OneofOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000001u; ::google::protobuf::FeatureSet* _msg = _internal_mutable_features(); // @@protoc_insertion_point(field_mutable:google.protobuf.OneofOptions.features) return _msg; @@ -17165,6 +16902,7 @@ inline bool EnumOptions::allow_alias() const { } inline void EnumOptions::set_allow_alias(bool value) { _internal_set_allow_alias(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.allow_alias) } inline bool EnumOptions::_internal_allow_alias() const { @@ -17173,7 +16911,6 @@ inline bool EnumOptions::_internal_allow_alias() const { } inline void EnumOptions::_internal_set_allow_alias(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.allow_alias_ = value; } @@ -17193,6 +16930,7 @@ inline bool EnumOptions::deprecated() const { } inline void EnumOptions::set_deprecated(bool value) { _internal_set_deprecated(value); + _impl_._has_bits_[0] |= 0x00000004u; // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.deprecated) } inline bool EnumOptions::_internal_deprecated() const { @@ -17201,7 +16939,6 @@ inline bool EnumOptions::_internal_deprecated() const { } inline void EnumOptions::_internal_set_deprecated(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000004u; _impl_.deprecated_ = value; } @@ -17221,6 +16958,7 @@ inline bool EnumOptions::deprecated_legacy_json_field_conflicts() const { } inline void EnumOptions::set_deprecated_legacy_json_field_conflicts(bool value) { _internal_set_deprecated_legacy_json_field_conflicts(value); + _impl_._has_bits_[0] |= 0x00000008u; // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.deprecated_legacy_json_field_conflicts) } inline bool EnumOptions::_internal_deprecated_legacy_json_field_conflicts() const { @@ -17229,7 +16967,6 @@ inline bool EnumOptions::_internal_deprecated_legacy_json_field_conflicts() cons } inline void EnumOptions::_internal_set_deprecated_legacy_json_field_conflicts(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000008u; _impl_.deprecated_legacy_json_field_conflicts_ = value; } @@ -17296,14 +17033,14 @@ inline ::google::protobuf::FeatureSet* EnumOptions::unsafe_arena_release_feature } inline ::google::protobuf::FeatureSet* EnumOptions::_internal_mutable_features() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000001u; if (_impl_.features_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::FeatureSet>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena()); _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p); } return _impl_.features_; } inline ::google::protobuf::FeatureSet* EnumOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000001u; ::google::protobuf::FeatureSet* _msg = _internal_mutable_features(); // @@protoc_insertion_point(field_mutable:google.protobuf.EnumOptions.features) return _msg; @@ -17398,6 +17135,7 @@ inline bool EnumValueOptions::deprecated() const { } inline void EnumValueOptions::set_deprecated(bool value) { _internal_set_deprecated(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.EnumValueOptions.deprecated) } inline bool EnumValueOptions::_internal_deprecated() const { @@ -17406,7 +17144,6 @@ inline bool EnumValueOptions::_internal_deprecated() const { } inline void EnumValueOptions::_internal_set_deprecated(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.deprecated_ = value; } @@ -17473,14 +17210,14 @@ inline ::google::protobuf::FeatureSet* EnumValueOptions::unsafe_arena_release_fe } inline ::google::protobuf::FeatureSet* EnumValueOptions::_internal_mutable_features() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000001u; if (_impl_.features_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::FeatureSet>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena()); _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p); } return _impl_.features_; } inline ::google::protobuf::FeatureSet* EnumValueOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000001u; ::google::protobuf::FeatureSet* _msg = _internal_mutable_features(); // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueOptions.features) return _msg; @@ -17522,6 +17259,7 @@ inline bool EnumValueOptions::debug_redact() const { } inline void EnumValueOptions::set_debug_redact(bool value) { _internal_set_debug_redact(value); + _impl_._has_bits_[0] |= 0x00000004u; // @@protoc_insertion_point(field_set:google.protobuf.EnumValueOptions.debug_redact) } inline bool EnumValueOptions::_internal_debug_redact() const { @@ -17530,7 +17268,6 @@ inline bool EnumValueOptions::_internal_debug_redact() const { } inline void EnumValueOptions::_internal_set_debug_redact(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000004u; _impl_.debug_redact_ = value; } @@ -17650,14 +17387,14 @@ inline ::google::protobuf::FeatureSet* ServiceOptions::unsafe_arena_release_feat } inline ::google::protobuf::FeatureSet* ServiceOptions::_internal_mutable_features() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000001u; if (_impl_.features_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::FeatureSet>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena()); _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p); } return _impl_.features_; } inline ::google::protobuf::FeatureSet* ServiceOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000001u; ::google::protobuf::FeatureSet* _msg = _internal_mutable_features(); // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceOptions.features) return _msg; @@ -17699,6 +17436,7 @@ inline bool ServiceOptions::deprecated() const { } inline void ServiceOptions::set_deprecated(bool value) { _internal_set_deprecated(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.ServiceOptions.deprecated) } inline bool ServiceOptions::_internal_deprecated() const { @@ -17707,7 +17445,6 @@ inline bool ServiceOptions::_internal_deprecated() const { } inline void ServiceOptions::_internal_set_deprecated(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.deprecated_ = value; } @@ -17780,6 +17517,7 @@ inline bool MethodOptions::deprecated() const { } inline void MethodOptions::set_deprecated(bool value) { _internal_set_deprecated(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.deprecated) } inline bool MethodOptions::_internal_deprecated() const { @@ -17788,7 +17526,6 @@ inline bool MethodOptions::_internal_deprecated() const { } inline void MethodOptions::_internal_set_deprecated(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.deprecated_ = value; } @@ -17808,6 +17545,7 @@ inline ::google::protobuf::MethodOptions_IdempotencyLevel MethodOptions::idempot } inline void MethodOptions::set_idempotency_level(::google::protobuf::MethodOptions_IdempotencyLevel value) { _internal_set_idempotency_level(value); + _impl_._has_bits_[0] |= 0x00000004u; // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.idempotency_level) } inline ::google::protobuf::MethodOptions_IdempotencyLevel MethodOptions::_internal_idempotency_level() const { @@ -17817,7 +17555,6 @@ inline ::google::protobuf::MethodOptions_IdempotencyLevel MethodOptions::_intern inline void MethodOptions::_internal_set_idempotency_level(::google::protobuf::MethodOptions_IdempotencyLevel value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::MethodOptions_IdempotencyLevel_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000004u; _impl_.idempotency_level_ = value; } @@ -17884,14 +17621,14 @@ inline ::google::protobuf::FeatureSet* MethodOptions::unsafe_arena_release_featu } inline ::google::protobuf::FeatureSet* MethodOptions::_internal_mutable_features() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000001u; if (_impl_.features_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::FeatureSet>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena()); _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p); } return _impl_.features_; } inline ::google::protobuf::FeatureSet* MethodOptions::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000001u; ::google::protobuf::FeatureSet* _msg = _internal_mutable_features(); // @@protoc_insertion_point(field_mutable:google.protobuf.MethodOptions.features) return _msg; @@ -18057,6 +17794,7 @@ inline bool UninterpretedOption_NamePart::is_extension() const { } inline void UninterpretedOption_NamePart::set_is_extension(bool value) { _internal_set_is_extension(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.is_extension) } inline bool UninterpretedOption_NamePart::_internal_is_extension() const { @@ -18065,7 +17803,6 @@ inline bool UninterpretedOption_NamePart::_internal_is_extension() const { } inline void UninterpretedOption_NamePart::_internal_set_is_extension(bool value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.is_extension_ = value; } @@ -18209,6 +17946,7 @@ inline ::uint64_t UninterpretedOption::positive_int_value() const { } inline void UninterpretedOption::set_positive_int_value(::uint64_t value) { _internal_set_positive_int_value(value); + _impl_._has_bits_[0] |= 0x00000008u; // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.positive_int_value) } inline ::uint64_t UninterpretedOption::_internal_positive_int_value() const { @@ -18217,7 +17955,6 @@ inline ::uint64_t UninterpretedOption::_internal_positive_int_value() const { } inline void UninterpretedOption::_internal_set_positive_int_value(::uint64_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000008u; _impl_.positive_int_value_ = value; } @@ -18237,6 +17974,7 @@ inline ::int64_t UninterpretedOption::negative_int_value() const { } inline void UninterpretedOption::set_negative_int_value(::int64_t value) { _internal_set_negative_int_value(value); + _impl_._has_bits_[0] |= 0x00000010u; // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.negative_int_value) } inline ::int64_t UninterpretedOption::_internal_negative_int_value() const { @@ -18245,7 +17983,6 @@ inline ::int64_t UninterpretedOption::_internal_negative_int_value() const { } inline void UninterpretedOption::_internal_set_negative_int_value(::int64_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000010u; _impl_.negative_int_value_ = value; } @@ -18265,6 +18002,7 @@ inline double UninterpretedOption::double_value() const { } inline void UninterpretedOption::set_double_value(double value) { _internal_set_double_value(value); + _impl_._has_bits_[0] |= 0x00000020u; // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.double_value) } inline double UninterpretedOption::_internal_double_value() const { @@ -18273,7 +18011,6 @@ inline double UninterpretedOption::_internal_double_value() const { } inline void UninterpretedOption::_internal_set_double_value(double value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000020u; _impl_.double_value_ = value; } @@ -18439,6 +18176,7 @@ inline ::google::protobuf::FeatureSet_FieldPresence FeatureSet::field_presence() } inline void FeatureSet::set_field_presence(::google::protobuf::FeatureSet_FieldPresence value) { _internal_set_field_presence(value); + _impl_._has_bits_[0] |= 0x00000001u; // @@protoc_insertion_point(field_set:google.protobuf.FeatureSet.field_presence) } inline ::google::protobuf::FeatureSet_FieldPresence FeatureSet::_internal_field_presence() const { @@ -18448,7 +18186,6 @@ inline ::google::protobuf::FeatureSet_FieldPresence FeatureSet::_internal_field_ inline void FeatureSet::_internal_set_field_presence(::google::protobuf::FeatureSet_FieldPresence value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FeatureSet_FieldPresence_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000001u; _impl_.field_presence_ = value; } @@ -18468,6 +18205,7 @@ inline ::google::protobuf::FeatureSet_EnumType FeatureSet::enum_type() const { } inline void FeatureSet::set_enum_type(::google::protobuf::FeatureSet_EnumType value) { _internal_set_enum_type(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.FeatureSet.enum_type) } inline ::google::protobuf::FeatureSet_EnumType FeatureSet::_internal_enum_type() const { @@ -18477,7 +18215,6 @@ inline ::google::protobuf::FeatureSet_EnumType FeatureSet::_internal_enum_type() inline void FeatureSet::_internal_set_enum_type(::google::protobuf::FeatureSet_EnumType value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FeatureSet_EnumType_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.enum_type_ = value; } @@ -18497,6 +18234,7 @@ inline ::google::protobuf::FeatureSet_RepeatedFieldEncoding FeatureSet::repeated } inline void FeatureSet::set_repeated_field_encoding(::google::protobuf::FeatureSet_RepeatedFieldEncoding value) { _internal_set_repeated_field_encoding(value); + _impl_._has_bits_[0] |= 0x00000004u; // @@protoc_insertion_point(field_set:google.protobuf.FeatureSet.repeated_field_encoding) } inline ::google::protobuf::FeatureSet_RepeatedFieldEncoding FeatureSet::_internal_repeated_field_encoding() const { @@ -18506,7 +18244,6 @@ inline ::google::protobuf::FeatureSet_RepeatedFieldEncoding FeatureSet::_interna inline void FeatureSet::_internal_set_repeated_field_encoding(::google::protobuf::FeatureSet_RepeatedFieldEncoding value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FeatureSet_RepeatedFieldEncoding_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000004u; _impl_.repeated_field_encoding_ = value; } @@ -18526,6 +18263,7 @@ inline ::google::protobuf::FeatureSet_Utf8Validation FeatureSet::utf8_validation } inline void FeatureSet::set_utf8_validation(::google::protobuf::FeatureSet_Utf8Validation value) { _internal_set_utf8_validation(value); + _impl_._has_bits_[0] |= 0x00000008u; // @@protoc_insertion_point(field_set:google.protobuf.FeatureSet.utf8_validation) } inline ::google::protobuf::FeatureSet_Utf8Validation FeatureSet::_internal_utf8_validation() const { @@ -18535,7 +18273,6 @@ inline ::google::protobuf::FeatureSet_Utf8Validation FeatureSet::_internal_utf8_ inline void FeatureSet::_internal_set_utf8_validation(::google::protobuf::FeatureSet_Utf8Validation value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FeatureSet_Utf8Validation_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000008u; _impl_.utf8_validation_ = value; } @@ -18555,6 +18292,7 @@ inline ::google::protobuf::FeatureSet_MessageEncoding FeatureSet::message_encodi } inline void FeatureSet::set_message_encoding(::google::protobuf::FeatureSet_MessageEncoding value) { _internal_set_message_encoding(value); + _impl_._has_bits_[0] |= 0x00000010u; // @@protoc_insertion_point(field_set:google.protobuf.FeatureSet.message_encoding) } inline ::google::protobuf::FeatureSet_MessageEncoding FeatureSet::_internal_message_encoding() const { @@ -18564,7 +18302,6 @@ inline ::google::protobuf::FeatureSet_MessageEncoding FeatureSet::_internal_mess inline void FeatureSet::_internal_set_message_encoding(::google::protobuf::FeatureSet_MessageEncoding value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FeatureSet_MessageEncoding_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000010u; _impl_.message_encoding_ = value; } @@ -18584,6 +18321,7 @@ inline ::google::protobuf::FeatureSet_JsonFormat FeatureSet::json_format() const } inline void FeatureSet::set_json_format(::google::protobuf::FeatureSet_JsonFormat value) { _internal_set_json_format(value); + _impl_._has_bits_[0] |= 0x00000020u; // @@protoc_insertion_point(field_set:google.protobuf.FeatureSet.json_format) } inline ::google::protobuf::FeatureSet_JsonFormat FeatureSet::_internal_json_format() const { @@ -18593,7 +18331,6 @@ inline ::google::protobuf::FeatureSet_JsonFormat FeatureSet::_internal_json_form inline void FeatureSet::_internal_set_json_format(::google::protobuf::FeatureSet_JsonFormat value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::FeatureSet_JsonFormat_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000020u; _impl_.json_format_ = value; } @@ -18617,6 +18354,7 @@ inline ::google::protobuf::Edition FeatureSetDefaults_FeatureSetEditionDefault:: } inline void FeatureSetDefaults_FeatureSetEditionDefault::set_edition(::google::protobuf::Edition value) { _internal_set_edition(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.edition) } inline ::google::protobuf::Edition FeatureSetDefaults_FeatureSetEditionDefault::_internal_edition() const { @@ -18626,7 +18364,6 @@ inline ::google::protobuf::Edition FeatureSetDefaults_FeatureSetEditionDefault:: inline void FeatureSetDefaults_FeatureSetEditionDefault::_internal_set_edition(::google::protobuf::Edition value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::Edition_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.edition_ = value; } @@ -18693,14 +18430,14 @@ inline ::google::protobuf::FeatureSet* FeatureSetDefaults_FeatureSetEditionDefau } inline ::google::protobuf::FeatureSet* FeatureSetDefaults_FeatureSetEditionDefault::_internal_mutable_features() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000001u; if (_impl_.features_ == nullptr) { - auto* p = CreateMaybeMessage<::google::protobuf::FeatureSet>(GetArena()); + auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::FeatureSet>(GetArena()); _impl_.features_ = reinterpret_cast<::google::protobuf::FeatureSet*>(p); } return _impl_.features_; } inline ::google::protobuf::FeatureSet* FeatureSetDefaults_FeatureSetEditionDefault::mutable_features() ABSL_ATTRIBUTE_LIFETIME_BOUND { + _impl_._has_bits_[0] |= 0x00000001u; ::google::protobuf::FeatureSet* _msg = _internal_mutable_features(); // @@protoc_insertion_point(field_mutable:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.features) return _msg; @@ -18795,6 +18532,7 @@ inline ::google::protobuf::Edition FeatureSetDefaults::minimum_edition() const { } inline void FeatureSetDefaults::set_minimum_edition(::google::protobuf::Edition value) { _internal_set_minimum_edition(value); + _impl_._has_bits_[0] |= 0x00000001u; // @@protoc_insertion_point(field_set:google.protobuf.FeatureSetDefaults.minimum_edition) } inline ::google::protobuf::Edition FeatureSetDefaults::_internal_minimum_edition() const { @@ -18804,7 +18542,6 @@ inline ::google::protobuf::Edition FeatureSetDefaults::_internal_minimum_edition inline void FeatureSetDefaults::_internal_set_minimum_edition(::google::protobuf::Edition value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::Edition_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000001u; _impl_.minimum_edition_ = value; } @@ -18824,6 +18561,7 @@ inline ::google::protobuf::Edition FeatureSetDefaults::maximum_edition() const { } inline void FeatureSetDefaults::set_maximum_edition(::google::protobuf::Edition value) { _internal_set_maximum_edition(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.FeatureSetDefaults.maximum_edition) } inline ::google::protobuf::Edition FeatureSetDefaults::_internal_maximum_edition() const { @@ -18833,7 +18571,6 @@ inline ::google::protobuf::Edition FeatureSetDefaults::_internal_maximum_edition inline void FeatureSetDefaults::_internal_set_maximum_edition(::google::protobuf::Edition value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::Edition_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.maximum_edition_ = value; } @@ -19363,6 +19100,7 @@ inline ::int32_t GeneratedCodeInfo_Annotation::begin() const { } inline void GeneratedCodeInfo_Annotation::set_begin(::int32_t value) { _internal_set_begin(value); + _impl_._has_bits_[0] |= 0x00000002u; // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.begin) } inline ::int32_t GeneratedCodeInfo_Annotation::_internal_begin() const { @@ -19371,7 +19109,6 @@ inline ::int32_t GeneratedCodeInfo_Annotation::_internal_begin() const { } inline void GeneratedCodeInfo_Annotation::_internal_set_begin(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000002u; _impl_.begin_ = value; } @@ -19391,6 +19128,7 @@ inline ::int32_t GeneratedCodeInfo_Annotation::end() const { } inline void GeneratedCodeInfo_Annotation::set_end(::int32_t value) { _internal_set_end(value); + _impl_._has_bits_[0] |= 0x00000004u; // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.end) } inline ::int32_t GeneratedCodeInfo_Annotation::_internal_end() const { @@ -19399,7 +19137,6 @@ inline ::int32_t GeneratedCodeInfo_Annotation::_internal_end() const { } inline void GeneratedCodeInfo_Annotation::_internal_set_end(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - _impl_._has_bits_[0] |= 0x00000004u; _impl_.end_ = value; } @@ -19419,6 +19156,7 @@ inline ::google::protobuf::GeneratedCodeInfo_Annotation_Semantic GeneratedCodeIn } inline void GeneratedCodeInfo_Annotation::set_semantic(::google::protobuf::GeneratedCodeInfo_Annotation_Semantic value) { _internal_set_semantic(value); + _impl_._has_bits_[0] |= 0x00000008u; // @@protoc_insertion_point(field_set:google.protobuf.GeneratedCodeInfo.Annotation.semantic) } inline ::google::protobuf::GeneratedCodeInfo_Annotation_Semantic GeneratedCodeInfo_Annotation::_internal_semantic() const { @@ -19428,7 +19166,6 @@ inline ::google::protobuf::GeneratedCodeInfo_Annotation_Semantic GeneratedCodeIn inline void GeneratedCodeInfo_Annotation::_internal_set_semantic(::google::protobuf::GeneratedCodeInfo_Annotation_Semantic value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); assert(::google::protobuf::GeneratedCodeInfo_Annotation_Semantic_IsValid(value)); - _impl_._has_bits_[0] |= 0x00000008u; _impl_.semantic_ = value; } diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto index 474864353a..ebb92c660e 100644 --- a/src/google/protobuf/descriptor.proto +++ b/src/google/protobuf/descriptor.proto @@ -81,6 +81,11 @@ enum Edition { EDITION_99997_TEST_ONLY = 99997; EDITION_99998_TEST_ONLY = 99998; EDITION_99999_TEST_ONLY = 99999; + + // Placeholder for specifying unbounded edition support. This should only + // ever be used by plugins that can expect to never require any changes to + // support a new edition. + EDITION_MAX = 0x7FFFFFFF; } // Describes a complete .proto file. @@ -202,7 +207,8 @@ message ExtensionRangeOptions { // The verification state of the range. // TODO: flip the default to DECLARATION once all empty ranges // are marked as UNVERIFIED. - optional VerificationState verification = 3 [default = UNVERIFIED]; + optional VerificationState verification = 3 + [default = UNVERIFIED, retention = RETENTION_SOURCE]; // Clients can define custom options in extensions of this message. See above. extensions 1000 to max; @@ -294,12 +300,12 @@ message FieldDescriptorProto { // If true, this is a proto3 "optional". When a proto3 field is optional, it // tracks presence regardless of field type. // - // When proto3_optional is true, this field must be belong to a oneof to - // signal to old proto3 clients that presence is tracked for this field. This - // oneof is known as a "synthetic" oneof, and this field must be its sole - // member (each proto3 optional field gets its own synthetic oneof). Synthetic - // oneofs exist in the descriptor only, and do not generate any API. Synthetic - // oneofs must be ordered after all "real" oneofs. + // When proto3_optional is true, this field must belong to a oneof to signal + // to old proto3 clients that presence is tracked for this field. This oneof + // is known as a "synthetic" oneof, and this field must be its sole member + // (each proto3 optional field gets its own synthetic oneof). Synthetic oneofs + // exist in the descriptor only, and do not generate any API. Synthetic oneofs + // must be ordered after all "real" oneofs. // // For message fields, proto3_optional doesn't create any semantic change, // since non-repeated message fields always track presence. However it still @@ -974,8 +980,8 @@ message FeatureSet { enum Utf8Validation { UTF8_VALIDATION_UNKNOWN = 0; - NONE = 1; VERIFY = 2; + NONE = 3; } optional Utf8Validation utf8_validation = 4 [ retention = RETENTION_RUNTIME, diff --git a/src/google/protobuf/descriptor_legacy.h b/src/google/protobuf/descriptor_legacy.h deleted file mode 100644 index e7a1f7c364..0000000000 --- a/src/google/protobuf/descriptor_legacy.h +++ /dev/null @@ -1,97 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd - -// Author: kenton@google.com (Kenton Varda) -// Based on original Protocol Buffers design by -// Sanjay Ghemawat, Jeff Dean, and others. -// -// This file contains classes which describe a type of protocol message. -// You can use a message's descriptor to learn at runtime what fields -// it contains and what the types of those fields are. The Message -// interface also allows you to dynamically access and modify individual -// fields by passing the FieldDescriptor of the field you are interested -// in. -// -// Most users will not care about descriptors, because they will write -// code specific to certain protocol types and will simply use the classes -// generated by the protocol compiler directly. Advanced users who want -// to operate on arbitrary types (not known at compile time) may want to -// read descriptors in order to learn about the contents of a message. -// A very small number of users will want to construct their own -// Descriptors, either because they are implementing Message manually or -// because they are writing something like the protocol compiler. -// -// For an example of how you might use descriptors, see the code example -// at the top of message.h. - -#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_LEGACY_H__ -#define GOOGLE_PROTOBUF_DESCRIPTOR_LEGACY_H__ - -#include "absl/strings/string_view.h" -#include "google/protobuf/descriptor.h" - -// Must be included last. -#include "google/protobuf/port_def.inc" - -// This file is meant to be a temporary housing for legacy descriptor APIs we -// want to deprecate and remove. This will help prevent backslide by allowing -// us to control visibility. - -namespace google { -namespace protobuf { -PROTOBUF_IGNORE_DEPRECATION_START - -// Wraps FileDescriptor. -class PROTOBUF_EXPORT FileDescriptorLegacy { - public: - explicit FileDescriptorLegacy(const FileDescriptor* desc) : desc_(desc) {} - - // Any dependencies on file-level syntax keyword should be replaced by - // feature-level switches to support go/protobuf-editions. - enum Syntax { - SYNTAX_UNKNOWN = FileDescriptor::SYNTAX_UNKNOWN, - SYNTAX_PROTO2 = FileDescriptor::SYNTAX_PROTO2, - SYNTAX_PROTO3 = FileDescriptor::SYNTAX_PROTO3, - SYNTAX_EDITIONS = FileDescriptor::SYNTAX_EDITIONS, - }; - Syntax syntax() const { return static_cast(desc_->syntax()); } - static absl::string_view SyntaxName(Syntax syntax) { - return FileDescriptor::SyntaxName( - static_cast(syntax)); - } - - private: - const FileDescriptor* desc_; -}; - -class PROTOBUF_EXPORT FieldDescriptorLegacy { - public: - explicit FieldDescriptorLegacy(const FieldDescriptor* desc) : desc_(desc) {} - - bool has_optional_keyword() const { return desc_->has_optional_keyword(); } - - private: - const FieldDescriptor* desc_; -}; - -class PROTOBUF_EXPORT OneofDescriptorLegacy { - public: - explicit OneofDescriptorLegacy(const OneofDescriptor* desc) : desc_(desc) {} - - bool is_synthetic() const { return desc_->is_synthetic(); } - - private: - const OneofDescriptor* desc_; -}; - -PROTOBUF_IGNORE_DEPRECATION_STOP -} // namespace protobuf -} // namespace google - -#include "google/protobuf/port_undef.inc" - -#endif // GOOGLE_PROTOBUF_DESCRIPTOR_LEGACY_H__ diff --git a/src/google/protobuf/descriptor_lite.h b/src/google/protobuf/descriptor_lite.h new file mode 100644 index 0000000000..db5805affe --- /dev/null +++ b/src/google/protobuf/descriptor_lite.h @@ -0,0 +1,87 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd +// +// This file contains definitions for the descriptors, so they can be used +// without importing descriptor.h + +#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_LITE_H__ +#define GOOGLE_PROTOBUF_DESCRIPTOR_LITE_H__ + +namespace google { +namespace protobuf { +namespace internal { + +class FieldDescriptorLite { + public: + // Identifies a field type. 0 is reserved for errors. + // The order is weird for historical reasons. + // Types 12 and up are new in proto2. + enum Type { + TYPE_DOUBLE = 1, // double, exactly eight bytes on the wire. + TYPE_FLOAT = 2, // float, exactly four bytes on the wire. + TYPE_INT64 = 3, // int64, varint on the wire. Negative numbers + // take 10 bytes. Use TYPE_SINT64 if negative + // values are likely. + TYPE_UINT64 = 4, // uint64, varint on the wire. + TYPE_INT32 = 5, // int32, varint on the wire. Negative numbers + // take 10 bytes. Use TYPE_SINT32 if negative + // values are likely. + TYPE_FIXED64 = 6, // uint64, exactly eight bytes on the wire. + TYPE_FIXED32 = 7, // uint32, exactly four bytes on the wire. + TYPE_BOOL = 8, // bool, varint on the wire. + TYPE_STRING = 9, // UTF-8 text. + TYPE_GROUP = 10, // Tag-delimited message. Deprecated. + TYPE_MESSAGE = 11, // Length-delimited message. + + TYPE_BYTES = 12, // Arbitrary byte array. + TYPE_UINT32 = 13, // uint32, varint on the wire + TYPE_ENUM = 14, // Enum, varint on the wire + TYPE_SFIXED32 = 15, // int32, exactly four bytes on the wire + TYPE_SFIXED64 = 16, // int64, exactly eight bytes on the wire + TYPE_SINT32 = 17, // int32, ZigZag-encoded varint on the wire + TYPE_SINT64 = 18, // int64, ZigZag-encoded varint on the wire + + MAX_TYPE = 18, // Constant useful for defining lookup tables + // indexed by Type. + }; + + // Specifies the C++ data type used to represent the field. There is a + // fixed mapping from Type to CppType where each Type maps to exactly one + // CppType. 0 is reserved for errors. + enum CppType { + CPPTYPE_INT32 = 1, // TYPE_INT32, TYPE_SINT32, TYPE_SFIXED32 + CPPTYPE_INT64 = 2, // TYPE_INT64, TYPE_SINT64, TYPE_SFIXED64 + CPPTYPE_UINT32 = 3, // TYPE_UINT32, TYPE_FIXED32 + CPPTYPE_UINT64 = 4, // TYPE_UINT64, TYPE_FIXED64 + CPPTYPE_DOUBLE = 5, // TYPE_DOUBLE + CPPTYPE_FLOAT = 6, // TYPE_FLOAT + CPPTYPE_BOOL = 7, // TYPE_BOOL + CPPTYPE_ENUM = 8, // TYPE_ENUM + CPPTYPE_STRING = 9, // TYPE_STRING, TYPE_BYTES + CPPTYPE_MESSAGE = 10, // TYPE_MESSAGE, TYPE_GROUP + + MAX_CPPTYPE = 10, // Constant useful for defining lookup tables + // indexed by CppType. + }; + + // Identifies whether the field is optional, required, or repeated. 0 is + // reserved for errors. + enum Label { + LABEL_OPTIONAL = 1, // optional + LABEL_REQUIRED = 2, // required + LABEL_REPEATED = 3, // repeated + + MAX_LABEL = 3, // Constant useful for defining lookup tables + // indexed by Label. + }; +}; + +} // namespace internal +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_DESCRIPTOR_LITE_H__ diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index 01dc123a83..703fb77861 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -14,6 +14,7 @@ #include "google/protobuf/descriptor.h" #include +#include #include #include #include @@ -30,20 +31,22 @@ #include #include "absl/container/btree_set.h" #include "absl/container/flat_hash_set.h" +#include "absl/functional/any_invocable.h" #include "absl/log/absl_check.h" #include "absl/log/absl_log.h" #include "absl/log/die_if_null.h" #include "absl/log/scoped_mock_log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" +#include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" #include "absl/strings/substitute.h" +#include "absl/synchronization/notification.h" #include "google/protobuf/compiler/importer.h" #include "google/protobuf/compiler/parser.h" #include "google/protobuf/cpp_features.pb.h" #include "google/protobuf/descriptor_database.h" -#include "google/protobuf/descriptor_legacy.h" #include "google/protobuf/dynamic_message.h" #include "google/protobuf/feature_resolver.h" #include "google/protobuf/io/tokenizer.h" @@ -75,12 +78,14 @@ template absl::Status GetStatus(const absl::StatusOr& s) { return s.status(); } -MATCHER_P(StatusIs, status, - absl::StrCat(".status() is ", testing::PrintToString(status))) { - return GetStatus(arg).code() == status; +MATCHER_P2(StatusIs, status, message, + absl::StrCat(".status() is ", testing::PrintToString(status))) { + return GetStatus(arg).code() == status && + testing::ExplainMatchResult(message, GetStatus(arg).message(), + result_listener); } -#define EXPECT_OK(x) EXPECT_THAT(x, StatusIs(absl::StatusCode::kOk)) -#define ASSERT_OK(x) ASSERT_THAT(x, StatusIs(absl::StatusCode::kOk)) +#define EXPECT_OK(x) EXPECT_THAT(x, StatusIs(absl::StatusCode::kOk, testing::_)) +#define ASSERT_OK(x) ASSERT_THAT(x, StatusIs(absl::StatusCode::kOk, testing::_)) namespace google { namespace protobuf { @@ -467,32 +472,30 @@ TEST_F(FileDescriptorTest, BuildAgainWithSyntax) { EXPECT_EQ(proto3_descriptor, pool_.BuildFile(proto_syntax3)); } -TEST_F(FileDescriptorTest, Syntax) { +TEST_F(FileDescriptorTest, Edition) { FileDescriptorProto proto; proto.set_name("foo"); - // Enable the test when we also populate the syntax for proto2. -#if 0 { proto.set_syntax("proto2"); DescriptorPool pool; const FileDescriptor* file = pool.BuildFile(proto); ASSERT_TRUE(file != nullptr); - EXPECT_EQ(FileDescriptorLegacy::Syntax::SYNTAX_PROTO2, FileDescriptorLegacy(file).syntax()); + EXPECT_EQ(file->edition(), Edition::EDITION_PROTO2); FileDescriptorProto other; file->CopyTo(&other); - EXPECT_EQ("proto2", other.syntax()); + EXPECT_EQ("", other.syntax()); + EXPECT_FALSE(other.has_edition()); } -#endif { proto.set_syntax("proto3"); DescriptorPool pool; const FileDescriptor* file = pool.BuildFile(proto); ASSERT_TRUE(file != nullptr); - EXPECT_EQ(FileDescriptorLegacy::Syntax::SYNTAX_PROTO3, - FileDescriptorLegacy(file).syntax()); + EXPECT_EQ(file->edition(), Edition::EDITION_PROTO3); FileDescriptorProto other; file->CopyTo(&other); EXPECT_EQ("proto3", other.syntax()); + EXPECT_FALSE(other.has_edition()); } { proto.set_syntax("editions"); @@ -500,8 +503,7 @@ TEST_F(FileDescriptorTest, Syntax) { DescriptorPool pool; const FileDescriptor* file = pool.BuildFile(proto); ASSERT_TRUE(file != nullptr); - EXPECT_EQ(FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS, - FileDescriptorLegacy(file).syntax()); + EXPECT_EQ(file->edition(), Edition::EDITION_2023); EXPECT_EQ(file->edition(), EDITION_2023); FileDescriptorProto other; file->CopyTo(&other); @@ -4013,7 +4015,7 @@ class ValidationErrorTest : public testing::Test { } // Parse file_text as a FileDescriptorProto in text format and add it // to the DescriptorPool. Expect no errors. - const FileDescriptor* BuildFile(const std::string& file_text) { + const FileDescriptor* BuildFile(absl::string_view file_text) { FileDescriptorProto file_proto; EXPECT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); return ABSL_DIE_IF_NULL(pool_.BuildFile(file_proto)); @@ -7032,10 +7034,73 @@ TEST_F(ValidationErrorTest, ValidateProto3EnumFromProto2) { " field { name:'bar' number:1 label:LABEL_OPTIONAL type:TYPE_ENUM " " type_name: 'foo.FooEnum' }" "}", - "bar.proto: Foo.bar: TYPE: Enum type \"foo.FooEnum\" is not a proto3 " + "bar.proto: Foo.bar: TYPE: Enum type \"foo.FooEnum\" is not an open " "enum, but is used in \"Foo\" which is a proto3 message type.\n"); } +TEST_F(ValidationErrorTest, ValidateProto3ClosedEnum) { + // Define a closed enum in an editions file. + BuildFile(R"pb(name: 'foo.proto' + package: 'foo' + syntax: 'editions' + edition: EDITION_2023 + enum_type { + name: 'FooEnum' + value { name: 'DEFAULT_OPTION' number: 0 } + options { features { enum_type: CLOSED } } + })pb"); + + BuildFileWithErrors( + R"pb(name: 'bar.proto' + dependency: 'foo.proto' + syntax: 'proto3' + message_type { + name: 'Foo' + field { + name: 'bar' + number: 1 + label: LABEL_OPTIONAL + type: TYPE_ENUM + type_name: 'foo.FooEnum' + } + })pb", + "bar.proto: Foo.bar: TYPE: Enum type \"foo.FooEnum\" is not an open " + "enum, but is used in \"Foo\" which is a proto3 message type.\n"); +} + +TEST_F(ValidationErrorTest, ValidateProto3OpenEnum) { + // Define an open enum in an editions file. + const FileDescriptor* foo = + BuildFile(R"pb(name: 'foo.proto' + package: 'foo' + syntax: 'editions' + edition: EDITION_2023 + enum_type { + name: 'FooEnum' + value { name: 'DEFAULT_OPTION' number: 0 } + })pb"); + const EnumDescriptor* enm = foo->enum_type(0); + ASSERT_NE(enm, nullptr); + + const FileDescriptor* bar = BuildFile( + R"pb(name: 'bar.proto' + dependency: 'foo.proto' + syntax: 'proto3' + message_type { + name: 'Foo' + field { + name: 'bar' + number: 1 + label: LABEL_OPTIONAL + type: TYPE_ENUM + type_name: 'foo.FooEnum' + } + })pb"); + ASSERT_NE(bar, nullptr); + + EXPECT_EQ(bar->message_type(0)->field(0)->enum_type(), enm); +} + TEST_F(ValidationErrorTest, ValidateProto3Extension) { // Valid for options. DescriptorPool pool; @@ -7238,7 +7303,7 @@ class FeaturesTest : public FeaturesBaseTest { GetExtensionReflection(pb::TestMessage::Nested::test_nested)}, EDITION_PROTO2, EDITION_99999_TEST_ONLY); ASSERT_OK(default_spec); - pool_.SetFeatureSetDefaults(std::move(default_spec).value()); + ASSERT_OK(pool_.SetFeatureSetDefaults(std::move(default_spec).value())); } }; @@ -7346,8 +7411,11 @@ TEST_F(FeaturesTest, Proto2Features) { [pb.cpp] { legacy_closed_enum: true })pb")); EXPECT_TRUE(field->has_presence()); EXPECT_FALSE(field->requires_utf8_validation()); - EXPECT_EQ(GetUtf8CheckMode(field, /*is_lite=*/false), Utf8CheckMode::kVerify); - EXPECT_EQ(GetUtf8CheckMode(field, /*is_lite=*/true), Utf8CheckMode::kNone); + EXPECT_EQ( + GetUtf8CheckMode(message->FindFieldByName("str"), /*is_lite=*/false), + Utf8CheckMode::kVerify); + EXPECT_EQ(GetUtf8CheckMode(message->FindFieldByName("str"), /*is_lite=*/true), + Utf8CheckMode::kNone); EXPECT_FALSE(field->is_packed()); EXPECT_FALSE(field->legacy_enum_field_treated_as_closed()); EXPECT_FALSE(HasPreservingUnknownEnumSemantics(field)); @@ -7412,8 +7480,11 @@ TEST_F(FeaturesTest, Proto3Features) { [pb.cpp] { legacy_closed_enum: false })pb")); EXPECT_FALSE(field->has_presence()); EXPECT_FALSE(field->requires_utf8_validation()); - EXPECT_EQ(GetUtf8CheckMode(field, /*is_lite=*/false), Utf8CheckMode::kStrict); - EXPECT_EQ(GetUtf8CheckMode(field, /*is_lite=*/true), Utf8CheckMode::kStrict); + EXPECT_EQ( + GetUtf8CheckMode(message->FindFieldByName("str"), /*is_lite=*/false), + Utf8CheckMode::kStrict); + EXPECT_EQ(GetUtf8CheckMode(message->FindFieldByName("str"), /*is_lite=*/true), + Utf8CheckMode::kStrict); EXPECT_FALSE(field->is_packed()); EXPECT_FALSE(field->legacy_enum_field_treated_as_closed()); EXPECT_FALSE(HasPreservingUnknownEnumSemantics(field)); @@ -9149,9 +9220,9 @@ TEST_F(FeaturesTest, FieldFeatureHelpers) { EXPECT_FALSE(default_repeated_field->has_presence()); EXPECT_FALSE(default_repeated_field->requires_utf8_validation()); EXPECT_EQ(GetUtf8CheckMode(default_repeated_field, /*is_lite=*/false), - Utf8CheckMode::kStrict); + Utf8CheckMode::kNone); EXPECT_EQ(GetUtf8CheckMode(default_repeated_field, /*is_lite=*/true), - Utf8CheckMode::kStrict); + Utf8CheckMode::kNone); EXPECT_TRUE(required_field->has_presence()); EXPECT_TRUE(required_field->is_required()); @@ -10327,6 +10398,100 @@ INSTANTIATE_TEST_SUITE_P( [](const ::testing::TestParamInfo& info) { return std::string(std::get<0>(info.param)); }); +using DescriptorPoolFeaturesTest = FeaturesBaseTest; + +TEST_F(DescriptorPoolFeaturesTest, BuildStarted) { + BuildDescriptorMessagesInTestPool(); + FeatureSetDefaults defaults = ParseTextOrDie(R"pb()pb"); + EXPECT_THAT(pool_.SetFeatureSetDefaults(std::move(defaults)), + StatusIs(absl::StatusCode::kFailedPrecondition, + HasSubstr("defaults can't be changed"))); +} + +TEST_F(DescriptorPoolFeaturesTest, InvalidRange) { + FeatureSetDefaults defaults = ParseTextOrDie(R"pb( + minimum_edition: EDITION_2023 + maximum_edition: EDITION_PROTO2 + )pb"); + EXPECT_THAT(pool_.SetFeatureSetDefaults(std::move(defaults)), + StatusIs(absl::StatusCode::kInvalidArgument, + AllOf(HasSubstr("Invalid edition range"), + HasSubstr("PROTO2"), HasSubstr("2023")))); +} + +TEST_F(DescriptorPoolFeaturesTest, UnknownDefaults) { + FeatureSetDefaults defaults = ParseTextOrDie(R"pb( + defaults { + edition: EDITION_UNKNOWN + features {} + } + minimum_edition: EDITION_PROTO2 + maximum_edition: EDITION_2023 + )pb"); + EXPECT_THAT(pool_.SetFeatureSetDefaults(std::move(defaults)), + StatusIs(absl::StatusCode::kInvalidArgument, + AllOf(HasSubstr("Invalid edition UNKNOWN")))); +} + +TEST_F(DescriptorPoolFeaturesTest, NotStrictlyIncreasing) { + FeatureSetDefaults defaults = ParseTextOrDie(R"pb( + defaults { + edition: EDITION_PROTO3 + features {} + } + defaults { + edition: EDITION_PROTO2 + features {} + } + minimum_edition: EDITION_PROTO2 + maximum_edition: EDITION_2023 + )pb"); + EXPECT_THAT( + pool_.SetFeatureSetDefaults(std::move(defaults)), + StatusIs( + absl::StatusCode::kInvalidArgument, + AllOf( + HasSubstr("not strictly increasing"), + HasSubstr("PROTO3 is greater than or equal to edition PROTO2")))); +} + +TEST_F(DescriptorPoolFeaturesTest, OverrideDefaults) { + FeatureSetDefaults defaults = ParseTextOrDie(R"pb( + defaults { + edition: EDITION_PROTO2 + features { + field_presence: EXPLICIT + enum_type: CLOSED + repeated_field_encoding: EXPANDED + utf8_validation: VERIFY + message_encoding: LENGTH_PREFIXED + json_format: ALLOW + } + } + minimum_edition: EDITION_PROTO2 + maximum_edition: EDITION_2023 + )pb"); + EXPECT_OK(pool_.SetFeatureSetDefaults(std::move(defaults))); + + FileDescriptorProto file_proto = ParseTextOrDie(R"pb( + name: "foo.proto" + syntax: "editions" + edition: EDITION_PROTO3 + )pb"); + + BuildDescriptorMessagesInTestPool(); + const FileDescriptor* file = ABSL_DIE_IF_NULL(pool_.BuildFile(file_proto)); + EXPECT_THAT(GetFeatures(file), EqualsProto(R"pb( + field_presence: EXPLICIT + enum_type: CLOSED + repeated_field_encoding: EXPANDED + utf8_validation: VERIFY + message_encoding: LENGTH_PREFIXED + json_format: ALLOW + )pb")); +} + + TEST_F(ValidationErrorTest, ExtensionDeclarationsMatchFullNameCompile) { diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc index a3838bdfa3..b9e1bf056d 100644 --- a/src/google/protobuf/duration.pb.cc +++ b/src/google/protobuf/duration.pb.cc @@ -1,5 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/duration.proto +// Protobuf C++ Version: 4.26.0-dev #include "google/protobuf/duration.pb.h" @@ -114,9 +115,6 @@ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fduration_2epr PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fduration_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2fduration_2eproto; } -// Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 -static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fduration_2eproto(&descriptor_table_google_2fprotobuf_2fduration_2eproto); namespace google { namespace protobuf { // =================================================================== @@ -162,12 +160,13 @@ inline void Duration::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* Duration::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { Duration::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(Duration, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void Duration::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Duration) @@ -203,6 +202,9 @@ const ::_pbi::TcParseTable<1, 2, 0, 0, 2> Duration::_table_ = { offsetof(decltype(_table_), field_names), // no aux_entries &_Duration_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::Duration>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // int32 nanos = 2; {::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(Duration, _impl_.nanos_), 63>(), @@ -279,7 +281,7 @@ const ::_pbi::TcParseTable<1, 2, 0, 0, 2> Duration::_table_ = { } -void Duration::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void Duration::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Duration) @@ -288,10 +290,10 @@ void Duration::MergeImpl(::google::protobuf::Message& to_msg, const ::google::pr (void) cached_has_bits; if (from._internal_seconds() != 0) { - _this->_internal_set_seconds(from._internal_seconds()); + _this->_impl_.seconds_ = from._impl_.seconds_; } if (from._internal_nanos() != 0) { - _this->_internal_set_nanos(from._internal_nanos()); + _this->_impl_.nanos_ = from._impl_.nanos_; } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -307,9 +309,6 @@ PROTOBUF_NOINLINE bool Duration::IsInitialized() const { return true; } -::_pbi::CachedSize* Duration::AccessCachedSize() const { - return &_impl_._cached_size_; -} void Duration::InternalSwap(Duration* PROTOBUF_RESTRICT other) { using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); @@ -322,9 +321,9 @@ void Duration::InternalSwap(Duration* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata Duration::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fduration_2eproto_getter, &descriptor_table_google_2fprotobuf_2fduration_2eproto_once, - file_level_metadata_google_2fprotobuf_2fduration_2eproto[0]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fduration_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fduration_2eproto_once, + file_level_metadata_google_2fprotobuf_2fduration_2eproto[0]); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf @@ -334,4 +333,8 @@ namespace protobuf { } // namespace protobuf } // namespace google // @@protoc_insertion_point(global_scope) +PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 +static ::std::false_type _static_init_ PROTOBUF_UNUSED = + (::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2fduration_2eproto), + ::std::false_type{}); #include "google/protobuf/port_undef.inc" diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h index 3a7539d2a3..816a6d715b 100644 --- a/src/google/protobuf/duration.pb.h +++ b/src/google/protobuf/duration.pb.h @@ -1,6 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/duration.proto -// Protobuf C++ Version: 4.24.0-main +// Protobuf C++ Version: 4.26.0-dev #ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fduration_2eproto_2epb_2eh #define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fduration_2eproto_2epb_2eh @@ -11,17 +11,11 @@ #include #include "google/protobuf/port_def.inc" -#if PROTOBUF_VERSION < 4024000 -#error "This file was generated by a newer version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please update" -#error "your headers." -#endif // PROTOBUF_VERSION - -#if 4024000 < PROTOBUF_MIN_PROTOC_VERSION -#error "This file was generated by an older version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please" -#error "regenerate this file with a newer version of protoc." -#endif // PROTOBUF_MIN_PROTOC_VERSION +#if PROTOBUF_VERSION != 4026000 +#error "Protobuf C++ gencode is built with an incompatible version of" +#error "Protobuf C++ headers/runtime. See" +#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp" +#endif #include "google/protobuf/port_undef.inc" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/arena.h" @@ -71,21 +65,18 @@ namespace protobuf { // ------------------------------------------------------------------- -class PROTOBUF_EXPORT Duration final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Duration) */ { +class PROTOBUF_EXPORT Duration final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.Duration) */ { public: inline Duration() : Duration(nullptr) {} ~Duration() override; - template - explicit PROTOBUF_CONSTEXPR Duration(::google::protobuf::internal::ConstantInitialized); - - inline Duration(const Duration& from) - : Duration(nullptr, from) {} - Duration(Duration&& from) noexcept - : Duration() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR Duration( + ::google::protobuf::internal::ConstantInitialized); + inline Duration(const Duration& from) : Duration(nullptr, from) {} + inline Duration(Duration&& from) noexcept + : Duration(nullptr, std::move(from)) {} inline Duration& operator=(const Duration& from) { CopyFrom(from); return *this; @@ -93,9 +84,9 @@ class PROTOBUF_EXPORT Duration final : inline Duration& operator=(Duration&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -127,22 +118,17 @@ class PROTOBUF_EXPORT Duration final : } static inline const Duration* internal_default_instance() { return reinterpret_cast( - &_Duration_default_instance_); - } - static constexpr int kIndexInFileMessages = - 0; - - friend void swap(Duration& a, Duration& b) { - a.Swap(&b); + &_Duration_default_instance_); } + static constexpr int kIndexInFileMessages = 0; + friend void swap(Duration& a, Duration& b) { a.Swap(&b); } inline void Swap(Duration* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -157,16 +143,18 @@ class PROTOBUF_EXPORT Duration final : // implements Message ---------------------------------------------- Duration* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const Duration& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const Duration& from) { - Duration::MergeImpl(*this, from); - } + void MergeFrom(const Duration& from) { Duration::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -174,32 +162,33 @@ class PROTOBUF_EXPORT Duration final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(Duration* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.Duration"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.Duration"; } + + protected: explicit Duration(::google::protobuf::Arena* arena); Duration(::google::protobuf::Arena* arena, const Duration& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + Duration(::google::protobuf::Arena* arena, Duration&& from) noexcept + : Duration(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kSecondsFieldNumber = 1, kNanosFieldNumber = 2, @@ -227,7 +216,6 @@ class PROTOBUF_EXPORT Duration final : // @@protoc_insertion_point(class_scope:google.protobuf.Duration) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 1, 2, 0, @@ -239,14 +227,13 @@ class PROTOBUF_EXPORT Duration final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::int64_t seconds_; ::int32_t nanos_; mutable ::google::protobuf::internal::CachedSize _cached_size_; @@ -291,7 +278,6 @@ inline ::int64_t Duration::_internal_seconds() const { } inline void Duration::_internal_set_seconds(::int64_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.seconds_ = value; } @@ -314,7 +300,6 @@ inline ::int32_t Duration::_internal_nanos() const { } inline void Duration::_internal_set_nanos(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.nanos_ = value; } diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index 64427553cc..d1f6ca6b7b 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc @@ -49,7 +49,6 @@ #include "google/protobuf/arenastring.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" -#include "google/protobuf/descriptor_legacy.h" #include "google/protobuf/extension_set.h" #include "google/protobuf/generated_message_reflection.h" #include "google/protobuf/generated_message_util.h" @@ -84,8 +83,7 @@ bool IsMapFieldInApi(const FieldDescriptor* field) { return field->is_map(); } inline bool InRealOneof(const FieldDescriptor* field) { - return field->containing_oneof() && - !OneofDescriptorLegacy(field->containing_oneof()).is_synthetic(); + return field->real_containing_oneof() != nullptr; } // Compute the byte size of the in-memory representation of the field. @@ -204,8 +202,14 @@ class DynamicMessage final : public Message { Message* New(Arena* arena) const override; - internal::CachedSize* AccessCachedSize() const final { - return &cached_byte_size_; + const ClassData* GetClassData() const final { + ABSL_CONST_INIT static const ClassData data = { + &MergeImpl, + nullptr, // on_demand_register_arena_dtor + &kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(DynamicMessage, cached_byte_size_), + }; + return &data; } Metadata GetMetadata() const override; @@ -345,16 +349,15 @@ void DynamicMessage::SharedCtor(bool lock_factory) { // constructor.) const Descriptor* descriptor = type_info_->type; + Arena* arena = GetArena(); // Initialize oneof cases. int oneof_count = 0; - for (int i = 0; i < descriptor->oneof_decl_count(); ++i) { - if (OneofDescriptorLegacy(descriptor->oneof_decl(i)).is_synthetic()) - continue; + for (int i = 0; i < descriptor->real_oneof_decl_count(); ++i) { new (MutableOneofCaseRaw(oneof_count++)) uint32_t{0}; } if (type_info_->extensions_offset != -1) { - new (MutableExtensionsRaw()) ExtensionSet(GetArena()); + new (MutableExtensionsRaw()) ExtensionSet(arena); } for (int i = 0; i < descriptor->field_count(); i++) { const FieldDescriptor* field = descriptor->field(i); @@ -368,7 +371,7 @@ void DynamicMessage::SharedCtor(bool lock_factory) { if (!field->is_repeated()) { \ new (field_ptr) TYPE(field->default_value_##TYPE()); \ } else { \ - new (field_ptr) RepeatedField(GetArena()); \ + new (field_ptr) RepeatedField(arena); \ } \ break; @@ -385,7 +388,7 @@ void DynamicMessage::SharedCtor(bool lock_factory) { if (!field->is_repeated()) { new (field_ptr) int{field->default_value_enum()->number()}; } else { - new (field_ptr) RepeatedField(GetArena()); + new (field_ptr) RepeatedField(arena); } break; @@ -397,7 +400,7 @@ void DynamicMessage::SharedCtor(bool lock_factory) { ArenaStringPtr* asp = new (field_ptr) ArenaStringPtr(); asp->InitDefault(); } else { - new (field_ptr) RepeatedPtrField(GetArena()); + new (field_ptr) RepeatedPtrField(arena); } break; } @@ -412,20 +415,20 @@ void DynamicMessage::SharedCtor(bool lock_factory) { // when the constructor is called inside GetPrototype(), in which // case we have already locked the factory. if (lock_factory) { - if (GetArena() != nullptr) { + if (arena != nullptr) { new (field_ptr) DynamicMapField( type_info_->factory->GetPrototype(field->message_type()), - GetArena()); + arena); } else { new (field_ptr) DynamicMapField( type_info_->factory->GetPrototype(field->message_type())); } } else { - if (GetArena() != nullptr) { + if (arena != nullptr) { new (field_ptr) DynamicMapField(type_info_->factory->GetPrototypeNoLock( field->message_type()), - GetArena()); + arena); } else { new (field_ptr) DynamicMapField(type_info_->factory->GetPrototypeNoLock( @@ -433,7 +436,7 @@ void DynamicMessage::SharedCtor(bool lock_factory) { } } } else { - new (field_ptr) RepeatedPtrField(GetArena()); + new (field_ptr) RepeatedPtrField(arena); } } break; @@ -620,7 +623,9 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( const Descriptor* type) { if (delegate_to_generated_factory_ && type->file()->pool() == DescriptorPool::generated_pool()) { - return MessageFactory::generated_factory()->GetPrototype(type); + const Message* result = MessageFactory::TryGetGeneratedPrototype(type); + if (result != nullptr) return result; + // Otherwise, we will create it dynamically so keep going. } const TypeInfo** target = &prototypes_[type]; @@ -643,12 +648,7 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( // this block. // - A big bitfield containing a bit for each field indicating whether // or not that field is set. - int real_oneof_count = 0; - for (int i = 0; i < type->oneof_decl_count(); i++) { - if (!OneofDescriptorLegacy(type->oneof_decl(i)).is_synthetic()) { - real_oneof_count++; - } - } + int real_oneof_count = type->real_oneof_decl_count(); // Compute size and offsets. uint32_t* offsets = new uint32_t[type->field_count() + real_oneof_count]; @@ -718,12 +718,10 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( } // The oneofs. - for (int i = 0; i < type->oneof_decl_count(); i++) { - if (!OneofDescriptorLegacy(type->oneof_decl(i)).is_synthetic()) { - size = AlignTo(size, kSafeAlignment); - offsets[type->field_count() + i] = size; - size += kMaxOneofUnionSize; - } + for (int i = 0; i < type->real_oneof_decl_count(); i++) { + size = AlignTo(size, kSafeAlignment); + offsets[type->field_count() + i] = size; + size += kMaxOneofUnionSize; } type_info->weak_field_map_offset = -1; @@ -736,10 +734,9 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( // Compute the size of default oneof instance and offsets of default // oneof fields. - for (int i = 0; i < type->oneof_decl_count(); i++) { - if (OneofDescriptorLegacy(type->oneof_decl(i)).is_synthetic()) continue; - for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { - const FieldDescriptor* field = type->oneof_decl(i)->field(j); + for (int i = 0; i < type->real_oneof_decl_count(); i++) { + for (int j = 0; j < type->real_oneof_decl(i)->field_count(); j++) { + const FieldDescriptor* field = type->real_oneof_decl(i)->field(j); // oneof fields are not accessed through offsets, but we still have the // entry from a legacy implementation. This should be removed at some // point. diff --git a/src/google/protobuf/editions/BUILD b/src/google/protobuf/editions/BUILD index 4489ffdbf8..96fc9b1385 100644 --- a/src/google/protobuf/editions/BUILD +++ b/src/google/protobuf/editions/BUILD @@ -1,6 +1,9 @@ +load("@rules_python//python:proto.bzl", "py_proto_library") +load("//bazel:upb_proto_library.bzl", "upb_c_proto_library", "upb_proto_reflection_library") load("@rules_cc//cc:defs.bzl", "cc_proto_library") load("@bazel_skylib//:bzl_library.bzl", "bzl_library") load(":defaults.bzl", "compile_edition_defaults", "embed_edition_defaults") +load("//:protobuf.bzl", "internal_objc_proto_library") bzl_library( name = "defaults", @@ -98,6 +101,34 @@ cc_proto_library( deps = [":test_messages_proto2_editions_proto"], ) +internal_objc_proto_library( + name = "test_messages_proto2_editions_objc_proto", + testonly = True, + srcs = ["golden/test_messages_proto2_editions.proto"], + enable_editions = True, + visibility = ["//conformance:__pkg__"], +) + +py_proto_library( + name = "test_messages_proto2_editions_py_pb2", + testonly = True, + visibility = ["//conformance:__pkg__"], + deps = [":test_messages_proto2_editions_proto"], +) + +upb_c_proto_library( + name = "test_messages_proto2_editions_upb_proto", + testonly = 1, + deps = [":test_messages_proto2_editions_proto"], +) + +upb_proto_reflection_library( + name = "test_messages_proto2_editions_upbdefs", + testonly = 1, + visibility = ["//upb/conformance:__pkg__"], + deps = [":test_messages_proto2_editions_proto"], +) + proto_library( name = "test_messages_proto3_editions_proto", testonly = True, @@ -120,6 +151,50 @@ cc_proto_library( deps = [":test_messages_proto3_editions_proto"], ) +internal_objc_proto_library( + name = "test_messages_proto3_editions_objc_proto", + testonly = True, + srcs = ["golden/test_messages_proto3_editions.proto"], + enable_editions = True, + includes = [ + ".", + "src", + ], + proto_deps = ["//:well_known_type_protos"], + visibility = ["//conformance:__pkg__"], +) + +py_proto_library( + name = "test_messages_proto3_editions_py_pb2", + testonly = True, + visibility = ["//conformance:__pkg__"], + deps = [":test_messages_proto3_editions_proto"], +) + +upb_c_proto_library( + name = "test_messages_proto3_editions_upb_proto", + testonly = 1, + deps = [":test_messages_proto3_editions_proto"], +) + +upb_proto_reflection_library( + name = "test_messages_proto3_editions_upbdefs", + testonly = 1, + visibility = ["//upb/conformance:__pkg__"], + deps = ["test_messages_proto3_editions_proto"], +) + +# Export these for conformance tests until we support py_proto_library. +exports_files( + [ + "golden/test_messages_proto2_editions.proto", + "golden/test_messages_proto3_editions.proto", + ], + visibility = [ + "//python:__pkg__", + ], +) + proto_library( name = "test_editions_default_features_proto", testonly = True, diff --git a/src/google/protobuf/editions/golden/compare_cpp_codegen_failure.txt b/src/google/protobuf/editions/golden/compare_cpp_codegen_failure.txt index 77046ed34f..03be36fe32 100644 --- a/src/google/protobuf/editions/golden/compare_cpp_codegen_failure.txt +++ b/src/google/protobuf/editions/golden/compare_cpp_codegen_failure.txt @@ -1,7 +1,7 @@ [ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.cc @@ @@ - &_SimpleProto3_default_instance_._instance, - ::_pbi::TcParser::GenericFallbackLite, // fallback + ::_pbi::TcParser::GetTable<::protobuf_editions_test::golden::SimpleProto3>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ - // optional int32 int32_field = 1; + // int32 int32_field = 1; diff --git a/src/google/protobuf/editions/golden/compare_cpp_codegen_failure.xml b/src/google/protobuf/editions/golden/compare_cpp_codegen_failure.xml index d2d397248f..4074bc2e17 100644 --- a/src/google/protobuf/editions/golden/compare_cpp_codegen_failure.xml +++ b/src/google/protobuf/editions/golden/compare_cpp_codegen_failure.xml @@ -2,7 +2,7 @@ - + diff --git a/src/google/protobuf/editions/golden/editions_transform_proto2.proto b/src/google/protobuf/editions/golden/editions_transform_proto2.proto index 0c483d1db4..0b60e80f36 100644 --- a/src/google/protobuf/editions/golden/editions_transform_proto2.proto +++ b/src/google/protobuf/editions/golden/editions_transform_proto2.proto @@ -10,7 +10,7 @@ edition = "2023"; // This file contains various edge cases we've collected from migrating real // protos in order to lock down the transformations. -// LINT:ALLOW_GROUPS +// LINT: ALLOW_GROUPS package protobuf_editions_test; @@ -34,7 +34,7 @@ service EmptyService { } service BasicService { - rpc BasicMethod(EmptyMessage) returns (EmptyMessage); + rpc BasicMethod(EmptyMessage) returns (EmptyMessage) {} } // clang-format off @@ -63,8 +63,8 @@ message ParentMessage { message ExtendedMessage { extensions 536860000 to 536869999 [ declaration = { - number: 536860000, - full_name: ".protobuf_editions_test.extension", + number: 536860000 + full_name: ".protobuf_editions_test.extension" type: ".protobuf_editions_test.EmptyMessage" } ]; diff --git a/src/google/protobuf/editions/golden/test_messages_proto2_editions.proto b/src/google/protobuf/editions/golden/test_messages_proto2_editions.proto index 3d9e9adf6f..9f4f198318 100644 --- a/src/google/protobuf/editions/golden/test_messages_proto2_editions.proto +++ b/src/google/protobuf/editions/golden/test_messages_proto2_editions.proto @@ -9,7 +9,7 @@ // // - conformance tests -// LINT:ALLOW_GROUPS +// LINT: ALLOW_GROUPS edition = "2023"; @@ -19,7 +19,7 @@ option features.enum_type = CLOSED; option features.repeated_field_encoding = EXPANDED; option features.utf8_validation = NONE; option java_package = "com.google.protobuf_test_messages.editions.proto2"; -option objc_class_prefix = "Proto2"; +option objc_class_prefix = "EditionsProto2"; // This is the default, but we specify it here explicitly. option optimize_for = SPEED; @@ -264,11 +264,11 @@ message TestAllTypesProto2 { ]; float default_float = 251 [ - default = 9.0E9 + default = 9e9 ]; double default_double = 252 [ - default = 7.0E22 + default = 7e22 ]; bool default_bool = 253 [ @@ -567,12 +567,12 @@ message TestAllRequiredTypesProto2 { float default_float = 251 [ features.field_presence = LEGACY_REQUIRED, - default = 9.0E9 + default = 9e9 ]; double default_double = 252 [ features.field_presence = LEGACY_REQUIRED, - default = 7.0E22 + default = 7e22 ]; bool default_bool = 253 [ diff --git a/src/google/protobuf/editions/golden/test_messages_proto3_editions.proto b/src/google/protobuf/editions/golden/test_messages_proto3_editions.proto index 9dbf63e6a5..c092ea6c8d 100644 --- a/src/google/protobuf/editions/golden/test_messages_proto3_editions.proto +++ b/src/google/protobuf/editions/golden/test_messages_proto3_editions.proto @@ -24,7 +24,7 @@ import "google/protobuf/wrappers.proto"; option features.field_presence = IMPLICIT; option java_package = "com.google.protobuf_test_messages.editions.proto3"; -option objc_class_prefix = "Proto3"; +option objc_class_prefix = "EditionsProto3"; // This is the default, but we specify it here explicitly. option optimize_for = SPEED; diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc index 0601bb4064..5304e38f72 100644 --- a/src/google/protobuf/empty.pb.cc +++ b/src/google/protobuf/empty.pb.cc @@ -1,5 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/empty.proto +// Protobuf C++ Version: 4.26.0-dev #include "google/protobuf/empty.pb.h" @@ -103,9 +104,6 @@ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fempty_2eproto PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fempty_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2fempty_2eproto; } -// Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 -static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fempty_2eproto(&descriptor_table_google_2fprotobuf_2fempty_2eproto); namespace google { namespace protobuf { // =================================================================== @@ -139,9 +137,9 @@ Empty::Empty( ::google::protobuf::Metadata Empty::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fempty_2eproto_getter, &descriptor_table_google_2fprotobuf_2fempty_2eproto_once, - file_level_metadata_google_2fprotobuf_2fempty_2eproto[0]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fempty_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fempty_2eproto_once, + file_level_metadata_google_2fprotobuf_2fempty_2eproto[0]); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf @@ -151,4 +149,8 @@ namespace protobuf { } // namespace protobuf } // namespace google // @@protoc_insertion_point(global_scope) +PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 +static ::std::false_type _static_init_ PROTOBUF_UNUSED = + (::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2fempty_2eproto), + ::std::false_type{}); #include "google/protobuf/port_undef.inc" diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h index f66a7258ec..75f41a09d3 100644 --- a/src/google/protobuf/empty.pb.h +++ b/src/google/protobuf/empty.pb.h @@ -1,6 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/empty.proto -// Protobuf C++ Version: 4.24.0-main +// Protobuf C++ Version: 4.26.0-dev #ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fempty_2eproto_2epb_2eh #define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fempty_2eproto_2epb_2eh @@ -11,17 +11,11 @@ #include #include "google/protobuf/port_def.inc" -#if PROTOBUF_VERSION < 4024000 -#error "This file was generated by a newer version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please update" -#error "your headers." -#endif // PROTOBUF_VERSION - -#if 4024000 < PROTOBUF_MIN_PROTOC_VERSION -#error "This file was generated by an older version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please" -#error "regenerate this file with a newer version of protoc." -#endif // PROTOBUF_MIN_PROTOC_VERSION +#if PROTOBUF_VERSION != 4026000 +#error "Protobuf C++ gencode is built with an incompatible version of" +#error "Protobuf C++ headers/runtime. See" +#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp" +#endif #include "google/protobuf/port_undef.inc" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/arena.h" @@ -72,20 +66,17 @@ namespace protobuf { // ------------------------------------------------------------------- -class PROTOBUF_EXPORT Empty final : - public ::google::protobuf::internal::ZeroFieldsBase /* @@protoc_insertion_point(class_definition:google.protobuf.Empty) */ { +class PROTOBUF_EXPORT Empty final : public ::google::protobuf::internal::ZeroFieldsBase +/* @@protoc_insertion_point(class_definition:google.protobuf.Empty) */ { public: inline Empty() : Empty(nullptr) {} - template - explicit PROTOBUF_CONSTEXPR Empty(::google::protobuf::internal::ConstantInitialized); - - inline Empty(const Empty& from) - : Empty(nullptr, from) {} - Empty(Empty&& from) noexcept - : Empty() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR Empty( + ::google::protobuf::internal::ConstantInitialized); + inline Empty(const Empty& from) : Empty(nullptr, from) {} + inline Empty(Empty&& from) noexcept + : Empty(nullptr, std::move(from)) {} inline Empty& operator=(const Empty& from) { CopyFrom(from); return *this; @@ -93,9 +84,9 @@ class PROTOBUF_EXPORT Empty final : inline Empty& operator=(Empty&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -127,22 +118,17 @@ class PROTOBUF_EXPORT Empty final : } static inline const Empty* internal_default_instance() { return reinterpret_cast( - &_Empty_default_instance_); - } - static constexpr int kIndexInFileMessages = - 0; - - friend void swap(Empty& a, Empty& b) { - a.Swap(&b); + &_Empty_default_instance_); } + static constexpr int kIndexInFileMessages = 0; + friend void swap(Empty& a, Empty& b) { a.Swap(&b); } inline void Swap(Empty* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -157,7 +143,7 @@ class PROTOBUF_EXPORT Empty final : // implements Message ---------------------------------------------- Empty* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::internal::ZeroFieldsBase::DefaultConstruct(arena); } using ::google::protobuf::internal::ZeroFieldsBase::CopyFrom; inline void CopyFrom(const Empty& from) { @@ -167,42 +153,41 @@ class PROTOBUF_EXPORT Empty final : void MergeFrom(const Empty& from) { ::google::protobuf::internal::ZeroFieldsBase::MergeImpl(*this, from); } - public: - private: + public: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.Empty"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.Empty"; } + + protected: explicit Empty(::google::protobuf::Arena* arena); Empty(::google::protobuf::Arena* arena, const Empty& from); - public: + Empty(::google::protobuf::Arena* arena, Empty&& from) noexcept + : Empty(arena) { + *this = ::std::move(from); + } + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - // @@protoc_insertion_point(class_scope:google.protobuf.Empty) private: class _Internal; - friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; template friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); PROTOBUF_TSAN_DECLARE_MEMBER }; friend struct ::TableStruct_google_2fprotobuf_2fempty_2eproto; diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc index 4b54d7a3b6..5328fa071a 100644 --- a/src/google/protobuf/extension_set.cc +++ b/src/google/protobuf/extension_set.cc @@ -11,14 +11,19 @@ #include "google/protobuf/extension_set.h" +#include +#include +#include +#include #include #include #include #include -#include "google/protobuf/stubs/common.h" #include "absl/container/flat_hash_set.h" #include "absl/hash/hash.h" +#include "absl/log/absl_check.h" +#include "absl/log/absl_log.h" #include "google/protobuf/arena.h" #include "google/protobuf/extension_set_inl.h" #include "google/protobuf/io/coded_stream.h" @@ -106,13 +111,11 @@ bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) { void ExtensionSet::RegisterExtension(const MessageLite* extendee, int number, FieldType type, bool is_repeated, - bool is_packed, - LazyEagerVerifyFnType verify_func) { + bool is_packed) { ABSL_CHECK_NE(type, WireFormatLite::TYPE_ENUM); ABSL_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE); ABSL_CHECK_NE(type, WireFormatLite::TYPE_GROUP); - ExtensionInfo info(extendee, number, type, is_repeated, is_packed, - verify_func); + ExtensionInfo info(extendee, number, type, is_repeated, is_packed); Register(info); } @@ -134,7 +137,7 @@ void ExtensionSet::RegisterEnumExtension(const MessageLite* extendee, bool is_repeated, bool is_packed, EnumValidityFunc* is_valid) { ABSL_CHECK_EQ(type, WireFormatLite::TYPE_ENUM); - ExtensionInfo info(extendee, number, type, is_repeated, is_packed, nullptr); + ExtensionInfo info(extendee, number, type, is_repeated, is_packed); info.enum_validity_check.func = CallNoArgValidityFunc; // See comment in CallNoArgValidityFunc() about why we use a c-style cast. info.enum_validity_check.arg = (void*)is_valid; @@ -145,11 +148,12 @@ void ExtensionSet::RegisterMessageExtension(const MessageLite* extendee, int number, FieldType type, bool is_repeated, bool is_packed, const MessageLite* prototype, - LazyEagerVerifyFnType verify_func) { + LazyEagerVerifyFnType verify_func, + LazyAnnotation is_lazy) { ABSL_CHECK(type == WireFormatLite::TYPE_MESSAGE || type == WireFormatLite::TYPE_GROUP); ExtensionInfo info(extendee, number, type, is_repeated, is_packed, - verify_func); + verify_func, is_lazy); info.message_info = {prototype}; Register(info); } @@ -626,38 +630,40 @@ void ExtensionSet::SetAllocatedMessage(int number, FieldType type, ClearExtension(number); return; } - ABSL_DCHECK(message->GetArena() == nullptr || message->GetArena() == arena_); - Arena* message_arena = message->GetArena(); + Arena* const arena = arena_; + Arena* const message_arena = message->GetArena(); + ABSL_DCHECK(message_arena == nullptr || message_arena == arena); + Extension* extension; if (MaybeNewExtension(number, descriptor, &extension)) { extension->type = type; ABSL_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); extension->is_repeated = false; extension->is_lazy = false; - if (message_arena == arena_) { + if (message_arena == arena) { extension->message_value = message; } else if (message_arena == nullptr) { extension->message_value = message; - arena_->Own(message); // not nullptr because not equal to message_arena + arena->Own(message); // not nullptr because not equal to message_arena } else { - extension->message_value = message->New(arena_); + extension->message_value = message->New(arena); extension->message_value->CheckTypeAndMergeFrom(*message); } } else { ABSL_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE); if (extension->is_lazy) { - extension->lazymessage_value->SetAllocatedMessage(message, arena_); + extension->lazymessage_value->SetAllocatedMessage(message, arena); } else { - if (arena_ == nullptr) { + if (arena == nullptr) { delete extension->message_value; } - if (message_arena == arena_) { + if (message_arena == arena) { extension->message_value = message; } else if (message_arena == nullptr) { extension->message_value = message; - arena_->Own(message); // not nullptr because not equal to message_arena + arena->Own(message); // not nullptr because not equal to message_arena } else { - extension->message_value = message->New(arena_); + extension->message_value = message->New(arena); extension->message_value->CheckTypeAndMergeFrom(*message); } } @@ -704,8 +710,9 @@ MessageLite* ExtensionSet::ReleaseMessage(int number, ABSL_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE); MessageLite* ret = nullptr; if (extension->is_lazy) { - ret = extension->lazymessage_value->ReleaseMessage(prototype, arena_); - if (arena_ == nullptr) { + Arena* const arena = arena_; + ret = extension->lazymessage_value->ReleaseMessage(prototype, arena); + if (arena == nullptr) { delete extension->lazymessage_value; } } else { @@ -733,9 +740,10 @@ MessageLite* ExtensionSet::UnsafeArenaReleaseMessage( ABSL_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE); MessageLite* ret = nullptr; if (extension->is_lazy) { + Arena* const arena = arena_; ret = extension->lazymessage_value->UnsafeArenaReleaseMessage(prototype, - arena_); - if (arena_ == nullptr) { + arena); + if (arena == nullptr) { delete extension->lazymessage_value; } } else { @@ -990,10 +998,11 @@ void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee, HANDLE_TYPE(STRING, string, RepeatedPtrField); #undef HANDLE_TYPE - case WireFormatLite::CPPTYPE_MESSAGE: + case WireFormatLite::CPPTYPE_MESSAGE: { + Arena* const arena = arena_; if (is_new) { extension->repeated_message_value = - Arena::CreateMessage>(arena_); + Arena::CreateMessage>(arena); } // We can't call RepeatedPtrField::MergeFrom() because // it would attempt to allocate new objects. @@ -1006,12 +1015,13 @@ void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee, extension->repeated_message_value) ->AddFromCleared>(); if (target == nullptr) { - target = other_message.New(arena_); + target = other_message.New(arena); extension->repeated_message_value->AddAllocated(target); } target->CheckTypeAndMergeFrom(other_message); } break; + } } } else { if (!other_extension.is_cleared) { @@ -1037,6 +1047,7 @@ void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee, other_extension.descriptor); break; case WireFormatLite::CPPTYPE_MESSAGE: { + Arena* const arena = arena_; Extension* extension; bool is_new = MaybeNewExtension(number, other_extension.descriptor, &extension); @@ -1047,14 +1058,14 @@ void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee, if (other_extension.is_lazy) { extension->is_lazy = true; extension->lazymessage_value = - other_extension.lazymessage_value->New(arena_); + other_extension.lazymessage_value->New(arena); extension->lazymessage_value->MergeFrom( GetPrototypeForLazyMessage(extendee, number), - *other_extension.lazymessage_value, arena_); + *other_extension.lazymessage_value, arena); } else { extension->is_lazy = false; extension->message_value = - other_extension.message_value->New(arena_); + other_extension.message_value->New(arena); extension->message_value->CheckTypeAndMergeFrom( *other_extension.message_value); } @@ -1066,7 +1077,7 @@ void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee, if (extension->is_lazy) { extension->lazymessage_value->MergeFrom( GetPrototypeForLazyMessage(extendee, number), - *other_extension.lazymessage_value, arena_); + *other_extension.lazymessage_value, arena); } else { extension->message_value->CheckTypeAndMergeFrom( other_extension.lazymessage_value->GetMessage( @@ -1075,7 +1086,7 @@ void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee, } else { if (extension->is_lazy) { extension->lazymessage_value - ->MutableMessage(*other_extension.message_value, arena_) + ->MutableMessage(*other_extension.message_value, arena) ->CheckTypeAndMergeFrom(*other_extension.message_value); } else { extension->message_value->CheckTypeAndMergeFrom( @@ -1093,9 +1104,9 @@ void ExtensionSet::InternalExtensionMergeFrom(const MessageLite* extendee, void ExtensionSet::Swap(const MessageLite* extendee, ExtensionSet* other) { #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && GetArena() == other->GetArena()) { + if (arena_ != nullptr && arena_ == other->arena_) { #else // PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() == other->GetArena()) { + if (arena_ == other->arena_) { #endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { @@ -1123,7 +1134,9 @@ void ExtensionSet::SwapExtension(const MessageLite* extendee, ExtensionSet* other, int number) { if (this == other) return; - if (GetArena() == other->GetArena()) { + Arena* const arena = arena_; + Arena* const other_arena = other->arena_; + if (arena == other_arena) { UnsafeShallowSwapExtension(other, number); return; } @@ -1140,23 +1153,20 @@ void ExtensionSet::SwapExtension(const MessageLite* extendee, // We do it this way to reuse the copy-across-arenas logic already // implemented in ExtensionSet's MergeFrom. ExtensionSet temp; - temp.InternalExtensionMergeFrom(extendee, number, *other_ext, - other->GetArena()); + temp.InternalExtensionMergeFrom(extendee, number, *other_ext, other_arena); Extension* temp_ext = temp.FindOrNull(number); other_ext->Clear(); - other->InternalExtensionMergeFrom(extendee, number, *this_ext, - this->GetArena()); + other->InternalExtensionMergeFrom(extendee, number, *this_ext, arena); this_ext->Clear(); InternalExtensionMergeFrom(extendee, number, *temp_ext, temp.GetArena()); } else if (this_ext == nullptr) { - InternalExtensionMergeFrom(extendee, number, *other_ext, other->GetArena()); - if (other->GetArena() == nullptr) other_ext->Free(); + InternalExtensionMergeFrom(extendee, number, *other_ext, other_arena); + if (other_arena == nullptr) other_ext->Free(); other->Erase(number); } else { - other->InternalExtensionMergeFrom(extendee, number, *this_ext, - this->GetArena()); - if (GetArena() == nullptr) this_ext->Free(); + other->InternalExtensionMergeFrom(extendee, number, *this_ext, arena); + if (arena == nullptr) this_ext->Free(); Erase(number); } } @@ -1169,7 +1179,7 @@ void ExtensionSet::UnsafeShallowSwapExtension(ExtensionSet* other, int number) { if (this_ext == other_ext) return; - ABSL_DCHECK_EQ(GetArena(), other->GetArena()); + ABSL_DCHECK_EQ(arena_, other->arena_); if (this_ext != nullptr && other_ext != nullptr) { std::swap(*this_ext, *other_ext); @@ -1185,16 +1195,17 @@ void ExtensionSet::UnsafeShallowSwapExtension(ExtensionSet* other, int number) { bool ExtensionSet::IsInitialized(const MessageLite* extendee) const { // Extensions are never required. However, we need to check that all // embedded messages are initialized. + Arena* const arena = arena_; if (PROTOBUF_PREDICT_FALSE(is_large())) { for (const auto& kv : *map_.large) { - if (!kv.second.IsInitialized(this, extendee, kv.first, arena_)) { + if (!kv.second.IsInitialized(this, extendee, kv.first, arena)) { return false; } } return true; } for (const KeyValue* it = flat_begin(); it != flat_end(); ++it) { - if (!it->second.IsInitialized(this, extendee, it->first, arena_)) { + if (!it->second.IsInitialized(this, extendee, it->first, arena)) { return false; } } @@ -1441,12 +1452,9 @@ size_t ExtensionSet::Extension::ByteSize(int number) const { HANDLE_TYPE(GROUP, Group, *message_value); #undef HANDLE_TYPE case WireFormatLite::TYPE_MESSAGE: { - if (is_lazy) { - // LazyField::ByteSizeLong includes sizeof(length). - result += lazymessage_value->ByteSizeLong(); - } else { - result += WireFormatLite::MessageSize(*message_value); - } + result += WireFormatLite::LengthDelimitedSize( + is_lazy ? lazymessage_value->ByteSizeLong() + : message_value->ByteSizeLong()); break; } @@ -1635,8 +1643,9 @@ void ExtensionSet::GrowCapacity(size_t minimum_new_capacity) { const KeyValue* begin = flat_begin(); const KeyValue* end = flat_end(); AllocatedData new_map; + Arena* const arena = arena_; if (new_flat_capacity > kMaximumFlatCapacity) { - new_map.large = Arena::Create(arena_); + new_map.large = Arena::Create(arena); LargeMap::iterator hint = new_map.large->begin(); for (const KeyValue* it = begin; it != end; ++it) { hint = new_map.large->insert(hint, {it->first, it->second}); @@ -1644,11 +1653,11 @@ void ExtensionSet::GrowCapacity(size_t minimum_new_capacity) { flat_size_ = static_cast(-1); ABSL_DCHECK(is_large()); } else { - new_map.flat = Arena::CreateArray(arena_, new_flat_capacity); + new_map.flat = Arena::CreateArray(arena, new_flat_capacity); std::copy(begin, end, new_map.flat); } - if (arena_ == nullptr) { + if (arena == nullptr) { DeleteFlatMap(begin, flat_capacity_); } flat_capacity_ = new_flat_capacity; @@ -1907,11 +1916,9 @@ size_t ExtensionSet::Extension::MessageSetItemByteSize(int number) const { our_size += io::CodedOutputStream::VarintSize32(number); // message - if (is_lazy) { - our_size += lazymessage_value->ByteSizeLong(); - } else { - our_size += WireFormatLite::MessageSize(*message_value); - } + our_size += WireFormatLite::LengthDelimitedSize( + is_lazy ? lazymessage_value->ByteSizeLong() + : message_value->ByteSizeLong()); return our_size; } @@ -1933,6 +1940,8 @@ LazyEagerVerifyFnType FindExtensionLazyEagerVerifyFn( return nullptr; } +std::atomic + ExtensionSet::maybe_create_lazy_extension_; } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index f45a1c858c..79754ba275 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -16,7 +16,10 @@ #define GOOGLE_PROTOBUF_EXTENSION_SET_H__ #include +#include #include +#include +#include #include #include #include @@ -29,8 +32,10 @@ #include "google/protobuf/internal_visibility.h" #include "google/protobuf/port.h" #include "google/protobuf/io/coded_stream.h" +#include "google/protobuf/message_lite.h" #include "google/protobuf/parse_context.h" #include "google/protobuf/repeated_field.h" +#include "google/protobuf/repeated_ptr_field.h" #include "google/protobuf/wire_format_lite.h" // clang-format off @@ -57,6 +62,7 @@ class FeatureSet; namespace internal { class FieldSkipper; // wire_format_lite.h class WireFormat; +void InitializeLazyExtensionSet(); } // namespace internal } // namespace protobuf } // namespace google @@ -85,17 +91,33 @@ typedef bool EnumValidityFunc(int number); // extensions that are not compiled in. typedef bool EnumValidityFuncWithArg(const void* arg, int number); +enum class LazyAnnotation : int8_t { + kUndefined = 0, + kLazy = 1, + kEager = 2, +}; + // Information about a registered extension. struct ExtensionInfo { constexpr ExtensionInfo() : enum_validity_check() {} + constexpr ExtensionInfo(const MessageLite* extendee, int param_number, + FieldType type_param, bool isrepeated, bool ispacked) + : message(extendee), + number(param_number), + type(type_param), + is_repeated(isrepeated), + is_packed(ispacked), + enum_validity_check() {} constexpr ExtensionInfo(const MessageLite* extendee, int param_number, FieldType type_param, bool isrepeated, bool ispacked, - LazyEagerVerifyFnType verify_func) + LazyEagerVerifyFnType verify_func, + LazyAnnotation islazy = LazyAnnotation::kUndefined) : message(extendee), number(param_number), type(type_param), is_repeated(isrepeated), is_packed(ispacked), + is_lazy(islazy), enum_validity_check(), lazy_eager_verify_func(verify_func) {} @@ -105,6 +127,7 @@ struct ExtensionInfo { FieldType type = 0; bool is_repeated = false; bool is_packed = false; + LazyAnnotation is_lazy = LazyAnnotation::kUndefined; struct EnumValidityCheck { EnumValidityFuncWithArg* func; @@ -131,6 +154,7 @@ struct ExtensionInfo { LazyEagerVerifyFnType lazy_eager_verify_func = nullptr; }; + // An ExtensionFinder is an object which looks up extension definitions. It // must implement this method: // @@ -188,8 +212,7 @@ class PROTOBUF_EXPORT ExtensionSet { // methods do. static void RegisterExtension(const MessageLite* extendee, int number, FieldType type, bool is_repeated, - bool is_packed, - LazyEagerVerifyFnType verify_func); + bool is_packed); static void RegisterEnumExtension(const MessageLite* extendee, int number, FieldType type, bool is_repeated, bool is_packed, EnumValidityFunc* is_valid); @@ -197,7 +220,8 @@ class PROTOBUF_EXPORT ExtensionSet { FieldType type, bool is_repeated, bool is_packed, const MessageLite* prototype, - LazyEagerVerifyFnType verify_func); + LazyEagerVerifyFnType verify_func, + LazyAnnotation is_lazy); // ================================================================= @@ -508,6 +532,8 @@ class PROTOBUF_EXPORT ExtensionSet { friend class google::protobuf::Reflection; friend class google::protobuf::internal::WireFormat; + friend void internal::InitializeLazyExtensionSet(); + const int32_t& GetRefInt32(int number, const int32_t& default_value) const; const int64_t& GetRefInt64(int number, const int64_t& default_value) const; const uint32_t& GetRefUInt32(int number, const uint32_t& default_value) const; @@ -579,7 +605,13 @@ class PROTOBUF_EXPORT ExtensionSet { virtual void UnusedKeyMethod(); // Dummy key method to avoid weak vtable. }; // Give access to function defined below to see LazyMessageExtension. - friend LazyMessageExtension* MaybeCreateLazyExtension(Arena* arena); + static LazyMessageExtension* MaybeCreateLazyExtensionImpl(Arena* arena); + static LazyMessageExtension* MaybeCreateLazyExtension(Arena* arena) { + auto* f = maybe_create_lazy_extension_.load(std::memory_order_relaxed); + return f != nullptr ? f(arena) : nullptr; + } + static std::atomic + maybe_create_lazy_extension_; struct Extension { // The order of these fields packs Extension into 24 bytes when using 8 // byte alignment. Consider this when adding or removing fields here. @@ -757,7 +789,7 @@ class PROTOBUF_EXPORT ExtensionSet { // someone // adds a new wire type. } - PROTOBUF_ASSUME(false); // switch handles all possible enum values + Unreachable(); // switch handles all possible enum values return false; } @@ -971,8 +1003,6 @@ inline void ExtensionSet::AddString(int number, FieldType type, // static inline MutableType Add(int number, ExtensionSet* set); // This is used by the ExtensionIdentifier constructor to register // the extension at dynamic initialization. -// template -// static void Register(int number, FieldType type, bool is_packed); // }; // // Not all of these methods make sense for all field types. For example, the @@ -998,6 +1028,8 @@ class PrimitiveTypeTraits { public: typedef Type ConstType; typedef Type MutableType; + using InitType = ConstType; + static const ConstType& FromInitType(const InitType& v) { return v; } typedef PrimitiveTypeTraits Singular; static constexpr bool kLifetimeBound = false; @@ -1008,12 +1040,6 @@ class PrimitiveTypeTraits { const ConstType& default_value); static inline void Set(int number, FieldType field_type, ConstType value, ExtensionSet* set); - template - static void Register(int number, FieldType type, bool is_packed, - LazyEagerVerifyFnType verify_func) { - ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number, - type, false, is_packed, verify_func); - } }; template @@ -1021,6 +1047,8 @@ class RepeatedPrimitiveTypeTraits { public: typedef Type ConstType; typedef Type MutableType; + using InitType = ConstType; + static const ConstType& FromInitType(const InitType& v) { return v; } typedef RepeatedPrimitiveTypeTraits Repeated; static constexpr bool kLifetimeBound = false; @@ -1043,12 +1071,6 @@ class RepeatedPrimitiveTypeTraits { ExtensionSet* set); static const RepeatedFieldType* GetDefaultRepeatedField(); - template - static void Register(int number, FieldType type, bool is_packed, - LazyEagerVerifyFnType verify_func) { - ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number, - type, true, is_packed, verify_func); - } }; class PROTOBUF_EXPORT RepeatedPrimitiveDefaults { @@ -1148,6 +1170,8 @@ class PROTOBUF_EXPORT StringTypeTraits { public: typedef const std::string& ConstType; typedef std::string* MutableType; + using InitType = ConstType; + static ConstType FromInitType(InitType v) { return v; } typedef StringTypeTraits Singular; static constexpr bool kLifetimeBound = true; @@ -1167,18 +1191,14 @@ class PROTOBUF_EXPORT StringTypeTraits { ExtensionSet* set) { return set->MutableString(number, field_type, nullptr); } - template - static void Register(int number, FieldType type, bool is_packed, - LazyEagerVerifyFnType verify_func) { - ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number, - type, false, is_packed, verify_func); - } }; class PROTOBUF_EXPORT RepeatedStringTypeTraits { public: typedef const std::string& ConstType; typedef std::string* MutableType; + using InitType = ConstType; + static ConstType FromInitType(InitType v) { return v; } typedef RepeatedStringTypeTraits Repeated; static constexpr bool kLifetimeBound = true; @@ -1225,13 +1245,6 @@ class PROTOBUF_EXPORT RepeatedStringTypeTraits { static const RepeatedFieldType* GetDefaultRepeatedField(); - template - static void Register(int number, FieldType type, bool is_packed, - LazyEagerVerifyFnType fn) { - ExtensionSet::RegisterExtension(&ExtendeeT::default_instance(), number, - type, true, is_packed, fn); - } - private: static void InitializeDefaultRepeatedFields(); static void DestroyDefaultRepeatedFields(); @@ -1247,6 +1260,8 @@ class EnumTypeTraits { public: typedef Type ConstType; typedef Type MutableType; + using InitType = ConstType; + static const ConstType& FromInitType(const InitType& v) { return v; } typedef EnumTypeTraits Singular; static constexpr bool kLifetimeBound = false; @@ -1264,14 +1279,6 @@ class EnumTypeTraits { ABSL_DCHECK(IsValid(value)); set->SetEnum(number, field_type, value, nullptr); } - template - static void Register(int number, FieldType type, bool is_packed, - LazyEagerVerifyFnType fn) { - // Avoid -Wunused-parameter - (void)fn; - ExtensionSet::RegisterEnumExtension(&ExtendeeT::default_instance(), number, - type, false, is_packed, IsValid); - } }; template @@ -1279,6 +1286,8 @@ class RepeatedEnumTypeTraits { public: typedef Type ConstType; typedef Type MutableType; + using InitType = ConstType; + static const ConstType& FromInitType(const InitType& v) { return v; } typedef RepeatedEnumTypeTraits Repeated; static constexpr bool kLifetimeBound = false; @@ -1333,14 +1342,6 @@ class RepeatedEnumTypeTraits { return reinterpret_cast*>( RepeatedPrimitiveTypeTraits::GetDefaultRepeatedField()); } - template - static void Register(int number, FieldType type, bool is_packed, - LazyEagerVerifyFnType fn) { - // Avoid -Wunused-parameter - (void)fn; - ExtensionSet::RegisterEnumExtension(&ExtendeeT::default_instance(), number, - type, true, is_packed, IsValid); - } }; // ------------------------------------------------------------------- @@ -1354,6 +1355,10 @@ class MessageTypeTraits { public: typedef const Type& ConstType; typedef Type* MutableType; + using InitType = const void*; + static ConstType FromInitType(InitType v) { + return *static_cast(v); + } typedef MessageTypeTraits Singular; static constexpr bool kLifetimeBound = true; @@ -1392,13 +1397,6 @@ class MessageTypeTraits { return static_cast( set->UnsafeArenaReleaseMessage(number, Type::default_instance())); } - template - static void Register(int number, FieldType type, bool is_packed, - LazyEagerVerifyFnType fn) { - ExtensionSet::RegisterMessageExtension(&ExtendeeT::default_instance(), - number, type, false, is_packed, - &Type::default_instance(), fn); - } }; // Used by WireFormatVerify to extract the verify function from the registry. @@ -1413,6 +1411,10 @@ class RepeatedMessageTypeTraits { public: typedef const Type& ConstType; typedef Type* MutableType; + using InitType = const void*; + static ConstType FromInitType(InitType v) { + return *static_cast(v); + } typedef RepeatedMessageTypeTraits Repeated; static constexpr bool kLifetimeBound = true; @@ -1459,13 +1461,6 @@ class RepeatedMessageTypeTraits { } static const RepeatedFieldType* GetDefaultRepeatedField(); - template - static void Register(int number, FieldType type, bool is_packed, - LazyEagerVerifyFnType fn) { - ExtensionSet::RegisterMessageExtension(&ExtendeeT::default_instance(), - number, type, true, is_packed, - &Type::default_instance(), fn); - } }; template @@ -1501,73 +1496,28 @@ class ExtensionIdentifier { typedef TypeTraitsType TypeTraits; typedef ExtendeeType Extendee; - ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value, - LazyEagerVerifyFnType verify_func = nullptr) - : number_(number), default_value_(default_value) { - Register(number, verify_func); - } + constexpr ExtensionIdentifier(int number, + typename TypeTraits::InitType default_value) + : number_(number), default_value_(default_value) {} + inline int number() const { return number_; } typename TypeTraits::ConstType default_value() const { - return default_value_; - } - - static void Register(int number, LazyEagerVerifyFnType verify_func) { - TypeTraits::template Register(number, field_type, is_packed, - verify_func); + return TypeTraits::FromInitType(default_value_); } typename TypeTraits::ConstType const& default_value_ref() const { - return default_value_; + return TypeTraits::FromInitType(default_value_); } private: const int number_; - typename TypeTraits::ConstType default_value_; + typename TypeTraits::InitType default_value_; }; // ------------------------------------------------------------------- // Generated accessors -// Used to retrieve a lazy extension, may return nullptr in some environments. -extern PROTOBUF_ATTRIBUTE_WEAK ExtensionSet::LazyMessageExtension* -MaybeCreateLazyExtension(Arena* arena); - -// Define a specialization of ExtensionIdentifier for bootstrapped extensions -// that we need to register lazily. -template <> -class ExtensionIdentifier, 11, - false> { - public: - using TypeTraits = MessageTypeTraits<::pb::CppFeatures>; - using Extendee = FeatureSet; - - explicit constexpr ExtensionIdentifier(int number) : number_(number) {} - - int number() const { return number_; } - const ::pb::CppFeatures& default_value() const { return *default_value_; } - - template - void LazyRegister( - const MessageType& default_instance = MessageType::default_instance(), - LazyEagerVerifyFnType verify_func = nullptr) const { - absl::call_once(once_, [&] { - default_value_ = &default_instance; - MessageTypeTraits::template Register( - number_, 11, false, verify_func); - }); - } - - const ::pb::CppFeatures& default_value_ref() const { return *default_value_; } - - private: - const int number_; - mutable const ::pb::CppFeatures* default_value_ = nullptr; - mutable absl::once_flag once_; -}; - - } // namespace internal // Call this function to ensure that this extensions's reflection is linked into diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc index 20530c14dc..ef3a794809 100644 --- a/src/google/protobuf/extension_set_heavy.cc +++ b/src/google/protobuf/extension_set_heavy.cc @@ -12,6 +12,8 @@ // Contains methods defined in extension_set.h which cannot be part of the // lite library because they use descriptors or reflection. +#include +#include #include #include "absl/log/absl_check.h" @@ -271,6 +273,11 @@ bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) { ABSL_CHECK(output->message_info.prototype != nullptr) << "Extension factory's GetPrototype() returned nullptr; extension: " << extension->full_name(); + + if (extension->options().has_lazy()) { + output->is_lazy = extension->options().lazy() ? LazyAnnotation::kLazy + : LazyAnnotation::kEager; + } } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { output->enum_validity_check.func = ValidateEnumUsingDescriptor; output->enum_validity_check.arg = extension->enum_type(); diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc index c65ebd96d1..cb969896a5 100644 --- a/src/google/protobuf/extension_set_unittest.cc +++ b/src/google/protobuf/extension_set_unittest.cc @@ -11,6 +11,9 @@ #include "google/protobuf/extension_set.h" +#include +#include + #include "google/protobuf/descriptor.pb.h" #include "google/protobuf/testing/googletest.h" #include @@ -27,6 +30,7 @@ #include "google/protobuf/test_util2.h" #include "google/protobuf/text_format.h" #include "google/protobuf/unittest.pb.h" +#include "google/protobuf/unittest.pb.h" #include "google/protobuf/unittest_mset.pb.h" #include "google/protobuf/wire_format.h" #include "google/protobuf/wire_format_lite.h" @@ -37,6 +41,8 @@ namespace google { namespace protobuf { + + namespace internal { namespace { diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc index 2c6c5badc2..4f7f02f9c4 100644 --- a/src/google/protobuf/field_mask.pb.cc +++ b/src/google/protobuf/field_mask.pb.cc @@ -1,5 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/field_mask.proto +// Protobuf C++ Version: 4.26.0-dev #include "google/protobuf/field_mask.pb.h" @@ -112,9 +113,6 @@ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2ffield_5fmask_ PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto; } -// Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 -static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2ffield_5fmask_2eproto(&descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto); namespace google { namespace protobuf { // =================================================================== @@ -168,12 +166,13 @@ inline void FieldMask::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* FieldMask::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { FieldMask::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(FieldMask, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void FieldMask::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FieldMask) @@ -207,6 +206,9 @@ const ::_pbi::TcParseTable<0, 1, 0, 39, 2> FieldMask::_table_ = { offsetof(decltype(_table_), field_names), // no aux_entries &_FieldMask_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::FieldMask>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // repeated string paths = 1; {::_pbi::TcParser::FastUR1, @@ -268,7 +270,7 @@ const ::_pbi::TcParseTable<0, 1, 0, 39, 2> FieldMask::_table_ = { } -void FieldMask::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void FieldMask::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldMask) @@ -291,9 +293,6 @@ PROTOBUF_NOINLINE bool FieldMask::IsInitialized() const { return true; } -::_pbi::CachedSize* FieldMask::AccessCachedSize() const { - return &_impl_._cached_size_; -} void FieldMask::InternalSwap(FieldMask* PROTOBUF_RESTRICT other) { using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); @@ -301,9 +300,9 @@ void FieldMask::InternalSwap(FieldMask* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata FieldMask::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_getter, &descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_once, - file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto[0]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_getter, + &descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto_once, + file_level_metadata_google_2fprotobuf_2ffield_5fmask_2eproto[0]); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf @@ -313,4 +312,8 @@ namespace protobuf { } // namespace protobuf } // namespace google // @@protoc_insertion_point(global_scope) +PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 +static ::std::false_type _static_init_ PROTOBUF_UNUSED = + (::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto), + ::std::false_type{}); #include "google/protobuf/port_undef.inc" diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h index e4d6dca8a2..0c3b691377 100644 --- a/src/google/protobuf/field_mask.pb.h +++ b/src/google/protobuf/field_mask.pb.h @@ -1,6 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/field_mask.proto -// Protobuf C++ Version: 4.24.0-main +// Protobuf C++ Version: 4.26.0-dev #ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ffield_5fmask_2eproto_2epb_2eh #define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ffield_5fmask_2eproto_2epb_2eh @@ -11,17 +11,11 @@ #include #include "google/protobuf/port_def.inc" -#if PROTOBUF_VERSION < 4024000 -#error "This file was generated by a newer version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please update" -#error "your headers." -#endif // PROTOBUF_VERSION - -#if 4024000 < PROTOBUF_MIN_PROTOC_VERSION -#error "This file was generated by an older version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please" -#error "regenerate this file with a newer version of protoc." -#endif // PROTOBUF_MIN_PROTOC_VERSION +#if PROTOBUF_VERSION != 4026000 +#error "Protobuf C++ gencode is built with an incompatible version of" +#error "Protobuf C++ headers/runtime. See" +#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp" +#endif #include "google/protobuf/port_undef.inc" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/arena.h" @@ -71,21 +65,18 @@ namespace protobuf { // ------------------------------------------------------------------- -class PROTOBUF_EXPORT FieldMask final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.FieldMask) */ { +class PROTOBUF_EXPORT FieldMask final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.FieldMask) */ { public: inline FieldMask() : FieldMask(nullptr) {} ~FieldMask() override; - template - explicit PROTOBUF_CONSTEXPR FieldMask(::google::protobuf::internal::ConstantInitialized); - - inline FieldMask(const FieldMask& from) - : FieldMask(nullptr, from) {} - FieldMask(FieldMask&& from) noexcept - : FieldMask() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR FieldMask( + ::google::protobuf::internal::ConstantInitialized); + inline FieldMask(const FieldMask& from) : FieldMask(nullptr, from) {} + inline FieldMask(FieldMask&& from) noexcept + : FieldMask(nullptr, std::move(from)) {} inline FieldMask& operator=(const FieldMask& from) { CopyFrom(from); return *this; @@ -93,9 +84,9 @@ class PROTOBUF_EXPORT FieldMask final : inline FieldMask& operator=(FieldMask&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -127,22 +118,17 @@ class PROTOBUF_EXPORT FieldMask final : } static inline const FieldMask* internal_default_instance() { return reinterpret_cast( - &_FieldMask_default_instance_); - } - static constexpr int kIndexInFileMessages = - 0; - - friend void swap(FieldMask& a, FieldMask& b) { - a.Swap(&b); + &_FieldMask_default_instance_); } + static constexpr int kIndexInFileMessages = 0; + friend void swap(FieldMask& a, FieldMask& b) { a.Swap(&b); } inline void Swap(FieldMask* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -157,16 +143,18 @@ class PROTOBUF_EXPORT FieldMask final : // implements Message ---------------------------------------------- FieldMask* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const FieldMask& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const FieldMask& from) { - FieldMask::MergeImpl(*this, from); - } + void MergeFrom(const FieldMask& from) { FieldMask::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -174,32 +162,33 @@ class PROTOBUF_EXPORT FieldMask final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(FieldMask* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.FieldMask"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.FieldMask"; } + + protected: explicit FieldMask(::google::protobuf::Arena* arena); FieldMask(::google::protobuf::Arena* arena, const FieldMask& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + FieldMask(::google::protobuf::Arena* arena, FieldMask&& from) noexcept + : FieldMask(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kPathsFieldNumber = 1, }; @@ -234,7 +223,6 @@ class PROTOBUF_EXPORT FieldMask final : // @@protoc_insertion_point(class_scope:google.protobuf.FieldMask) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 0, 1, 0, @@ -246,14 +234,13 @@ class PROTOBUF_EXPORT FieldMask final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::RepeatedPtrField paths_; mutable ::google::protobuf::internal::CachedSize _cached_size_; PROTOBUF_TSAN_DECLARE_MEMBER diff --git a/src/google/protobuf/generated_message_bases.cc b/src/google/protobuf/generated_message_bases.cc index 5821ac6157..90a7921eb7 100644 --- a/src/google/protobuf/generated_message_bases.cc +++ b/src/google/protobuf/generated_message_bases.cc @@ -10,6 +10,7 @@ #include "google/protobuf/generated_message_reflection.h" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/io/zero_copy_stream_impl.h" +#include "google/protobuf/message_lite.h" #include "google/protobuf/parse_context.h" #include "google/protobuf/unknown_field_set.h" #include "google/protobuf/wire_format.h" @@ -76,7 +77,8 @@ failure: return target; } -void ZeroFieldsBase::MergeImpl(Message& to_param, const Message& from_param) { +void ZeroFieldsBase::MergeImpl(MessageLite& to_param, + const MessageLite& from_param) { auto* to = static_cast(&to_param); const auto* from = static_cast(&from_param); ABSL_DCHECK_NE(from, to); @@ -96,10 +98,11 @@ void ZeroFieldsBase::InternalSwap(ZeroFieldsBase* other) { } const Message::ClassData* ZeroFieldsBase::GetClassData() const { - static constexpr ClassData data = { + ABSL_CONST_INIT static const ClassData data = { &MergeImpl, - nullptr, + nullptr, // on_demand_register_arena_dtor &kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(ZeroFieldsBase, _cached_size_), }; return &data; } diff --git a/src/google/protobuf/generated_message_bases.h b/src/google/protobuf/generated_message_bases.h index 0f5e398a53..9e649d62ce 100644 --- a/src/google/protobuf/generated_message_bases.h +++ b/src/google/protobuf/generated_message_bases.h @@ -39,10 +39,6 @@ class PROTOBUF_EXPORT ZeroFieldsBase : public Message { io::EpsCopyOutputStream* stream) const final; protected: - internal::CachedSize* AccessCachedSize() const final { - return &_cached_size_; - } - constexpr ZeroFieldsBase() {} explicit ZeroFieldsBase(Arena* arena) : Message(arena) {} ZeroFieldsBase(const ZeroFieldsBase&) = delete; @@ -51,7 +47,7 @@ class PROTOBUF_EXPORT ZeroFieldsBase : public Message { const ClassData* GetClassData() const final; - static void MergeImpl(Message& to, const Message& from); + static void MergeImpl(MessageLite& to, const MessageLite& from); static void CopyImpl(Message& to, const Message& from); void InternalSwap(ZeroFieldsBase* other); diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index 452fd5240d..647b4cc747 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include "absl/base/call_once.h" #include "absl/base/casts.h" @@ -29,7 +30,6 @@ #include "absl/synchronization/mutex.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" -#include "google/protobuf/descriptor_legacy.h" #include "google/protobuf/extension_set.h" #include "google/protobuf/generated_message_tctable_decl.h" #include "google/protobuf/generated_message_tctable_gen.h" @@ -38,6 +38,7 @@ #include "google/protobuf/inlined_string_field.h" #include "google/protobuf/map_field.h" #include "google/protobuf/map_field_inl.h" +#include "google/protobuf/message.h" #include "google/protobuf/raw_ptr.h" #include "google/protobuf/repeated_field.h" #include "google/protobuf/unknown_field_set.h" @@ -93,6 +94,9 @@ void InitializeFileDescriptorDefaultInstances() { #endif // !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) } +void InitializeLazyExtensionSet() { +} + bool ParseNamedEnum(const EnumDescriptor* descriptor, absl::string_view name, int* value) { const EnumValueDescriptor* d = descriptor->FindValueByName(name); @@ -1003,7 +1007,7 @@ void Reflection::SwapOneofField(Message* lhs, Message* rhs, const FieldDescriptor* field; }; - ABSL_DCHECK(!OneofDescriptorLegacy(oneof_descriptor).is_synthetic()); + ABSL_DCHECK(!oneof_descriptor->is_synthetic()); uint32_t oneof_case_lhs = GetOneofCase(*lhs, oneof_descriptor); uint32_t oneof_case_rhs = GetOneofCase(*rhs, oneof_descriptor); @@ -1040,21 +1044,24 @@ void Reflection::SwapOneofField(Message* lhs, Message* rhs, } } -void Reflection::Swap(Message* message1, Message* message2) const { - if (message1 == message2) return; +void Reflection::Swap(Message* lhs, Message* rhs) const { + if (lhs == rhs) return; + + Arena* lhs_arena = lhs->GetArena(); + Arena* rhs_arena = rhs->GetArena(); // TODO: Other Reflection methods should probably check this too. - ABSL_CHECK_EQ(message1->GetReflection(), this) + ABSL_CHECK_EQ(lhs->GetReflection(), this) << "First argument to Swap() (of type \"" - << message1->GetDescriptor()->full_name() + << lhs->GetDescriptor()->full_name() << "\") is not compatible with this reflection object (which is for type " "\"" << descriptor_->full_name() << "\"). Note that the exact same class is required; not just the same " "descriptor."; - ABSL_CHECK_EQ(message2->GetReflection(), this) + ABSL_CHECK_EQ(rhs->GetReflection(), this) << "Second argument to Swap() (of type \"" - << message2->GetDescriptor()->full_name() + << rhs->GetDescriptor()->full_name() << "\") is not compatible with this reflection object (which is for type " "\"" << descriptor_->full_name() @@ -1064,32 +1071,31 @@ void Reflection::Swap(Message* message1, Message* message2) const { // Check that both messages are in the same arena (or both on the heap). We // need to copy all data if not, due to ownership semantics. #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (message1->GetArena() == nullptr || - message1->GetArena() != message2->GetArena()) { + if (lhs_arena == nullptr || lhs_arena != rhs_arena) { #else // PROTOBUF_FORCE_COPY_IN_SWAP - if (message1->GetArena() != message2->GetArena()) { + if (lhs_arena != rhs_arena) { #endif // !PROTOBUF_FORCE_COPY_IN_SWAP // One of the two is guaranteed to have an arena. Switch things around - // to guarantee that message1 has an arena. - Arena* arena = message1->GetArena(); + // to guarantee that lhs has an arena. + Arena* arena = lhs_arena; if (arena == nullptr) { - arena = message2->GetArena(); - std::swap(message1, message2); // Swapping names for pointers! + arena = rhs_arena; + std::swap(lhs, rhs); // Swapping names for pointers! } - Message* temp = message1->New(arena); - temp->MergeFrom(*message2); - message2->CopyFrom(*message1); + Message* temp = lhs->New(arena); + temp->MergeFrom(*rhs); + rhs->CopyFrom(*lhs); #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - message1->CopyFrom(*temp); + lhs->CopyFrom(*temp); if (arena == nullptr) delete temp; #else // PROTOBUF_FORCE_COPY_IN_SWAP - Swap(message1, temp); + Swap(lhs, temp); #endif // !PROTOBUF_FORCE_COPY_IN_SWAP return; } - UnsafeArenaSwap(message1, message2); + UnsafeArenaSwap(lhs, rhs); } template @@ -1223,12 +1229,10 @@ void Reflection::InternalSwap(Message* lhs, Message* rhs) const { if (schema_.IsSplit()) { std::swap(*MutableSplitField(lhs), *MutableSplitField(rhs)); } - const int oneof_decl_count = descriptor_->oneof_decl_count(); + const int oneof_decl_count = descriptor_->real_oneof_decl_count(); for (int i = 0; i < oneof_decl_count; i++) { - const OneofDescriptor* oneof = descriptor_->oneof_decl(i); - if (!OneofDescriptorLegacy(oneof).is_synthetic()) { - SwapOneofField(lhs, rhs, oneof); - } + const OneofDescriptor* oneof = descriptor_->real_oneof_decl(i); + SwapOneofField(lhs, rhs, oneof); } // Swapping bits need to happen after swapping fields, because the latter may @@ -2314,27 +2318,34 @@ void Reflection::SetAllocatedMessage(Message* message, Message* sub_message, ABSL_DCHECK(sub_message == nullptr || sub_message->GetArena() == nullptr || sub_message->GetArena() == message->GetArena()); + if (sub_message == nullptr) { + UnsafeArenaSetAllocatedMessage(message, nullptr, field); + return; + } + + Arena* arena = message->GetArena(); + Arena* sub_arena = sub_message->GetArena(); + if (arena == sub_arena) { + UnsafeArenaSetAllocatedMessage(message, sub_message, field); + return; + } + // If message and sub-message are in different memory ownership domains // (different arenas, or one is on heap and one is not), then we may need to // do a copy. - if (sub_message != nullptr && - sub_message->GetArena() != message->GetArena()) { - if (sub_message->GetArena() == nullptr && message->GetArena() != nullptr) { - // Case 1: parent is on an arena and child is heap-allocated. We can add - // the child to the arena's Own() list to free on arena destruction, then - // set our pointer. - message->GetArena()->Own(sub_message); - UnsafeArenaSetAllocatedMessage(message, sub_message, field); - } else { - // Case 2: all other cases. We need to make a copy. MutableMessage() will - // either get the existing message object, or instantiate a new one as - // appropriate w.r.t. our arena. - Message* sub_message_copy = MutableMessage(message, field); - sub_message_copy->CopyFrom(*sub_message); - } - } else { - // Same memory ownership domains. + if (sub_arena == nullptr) { + ABSL_DCHECK_NE(arena, nullptr); + // Case 1: parent is on an arena and child is heap-allocated. We can add + // the child to the arena's Own() list to free on arena destruction, then + // set our pointer. + arena->Own(sub_message); UnsafeArenaSetAllocatedMessage(message, sub_message, field); + } else { + // Case 2: all other cases. We need to make a copy. MutableMessage() will + // either get the existing message object, or instantiate a new one as + // appropriate w.r.t. our arena. + Message* sub_message_copy = MutableMessage(message, field); + sub_message_copy->CopyFrom(*sub_message); } } @@ -2560,7 +2571,7 @@ const void* Reflection::GetRawRepeatedField(const Message& message, const FieldDescriptor* Reflection::GetOneofFieldDescriptor( const Message& message, const OneofDescriptor* oneof_descriptor) const { - if (OneofDescriptorLegacy(oneof_descriptor).is_synthetic()) { + if (oneof_descriptor->is_synthetic()) { const FieldDescriptor* field = oneof_descriptor->field(0); return HasField(message, field) ? field : nullptr; } @@ -2642,11 +2653,6 @@ const FieldDescriptor* Reflection::FindKnownExtensionByNumber( return descriptor_pool_->FindExtensionByNumber(descriptor_, number); } -bool Reflection::SupportsUnknownEnumValues() const { - return FileDescriptorLegacy(descriptor_->file()).syntax() == - FileDescriptorLegacy::Syntax::SYNTAX_PROTO3; -} - // =================================================================== // Some private helpers. @@ -2745,14 +2751,14 @@ uint32_t* Reflection::MutableHasBits(Message* message) const { uint32_t Reflection::GetOneofCase( const Message& message, const OneofDescriptor* oneof_descriptor) const { - ABSL_DCHECK(!OneofDescriptorLegacy(oneof_descriptor).is_synthetic()); + ABSL_DCHECK(!oneof_descriptor->is_synthetic()); return internal::GetConstRefAtOffset( message, schema_.GetOneofCaseOffset(oneof_descriptor)); } uint32_t* Reflection::MutableOneofCase( Message* message, const OneofDescriptor* oneof_descriptor) const { - ABSL_DCHECK(!OneofDescriptorLegacy(oneof_descriptor).is_synthetic()); + ABSL_DCHECK(!oneof_descriptor->is_synthetic()); return GetPointerAtOffset( message, schema_.GetOneofCaseOffset(oneof_descriptor)); } @@ -2946,7 +2952,7 @@ void Reflection::SwapBit(Message* message1, Message* message2, bool Reflection::HasOneof(const Message& message, const OneofDescriptor* oneof_descriptor) const { - if (OneofDescriptorLegacy(oneof_descriptor).is_synthetic()) { + if (oneof_descriptor->is_synthetic()) { return HasField(message, oneof_descriptor->field(0)); } return (GetOneofCase(message, oneof_descriptor) > 0); @@ -2966,7 +2972,7 @@ void Reflection::ClearOneofField(Message* message, void Reflection::ClearOneof(Message* message, const OneofDescriptor* oneof_descriptor) const { - if (OneofDescriptorLegacy(oneof_descriptor).is_synthetic()) { + if (oneof_descriptor->is_synthetic()) { ClearField(message, oneof_descriptor->field(0)); return; } @@ -3218,8 +3224,19 @@ const internal::TcParseTableBase* Reflection::CreateTcParseTableReflectionOnly() // `operator delete` unconditionally. void* p = ::operator new(sizeof(Table)); auto* full_table = ::new (p) - Table{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, schema_.default_instance_, nullptr}, + Table{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, schema_.default_instance_, nullptr +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE + , + nullptr +#endif // PROTOBUF_PREFETCH_PARSE_TABLE + }, {{{&internal::TcParser::ReflectionParseLoop, {}}}}}; +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE + // We'll prefetch `to_prefetch->to_prefetch` unconditionally to avoid + // branches. Here we don't know which field is the hottest, so set the pointer + // to itself to avoid nullptr. + full_table->header.to_prefetch = &full_table->header; +#endif // PROTOBUF_PREFETCH_PARSE_TABLE ABSL_DCHECK_EQ(static_cast(&full_table->header), static_cast(full_table)); return &full_table->header; @@ -3412,6 +3429,7 @@ const internal::TcParseTableBase* Reflection::CreateTcParseTable() const { { /* is_lite */ false, /* uses_codegen */ false, + /* should_profile_driven_cluster_aux_table */ false, }, ReflectionOptionProvider(*this), has_bit_indices, inlined_string_indices); @@ -3448,7 +3466,18 @@ const internal::TcParseTableBase* Reflection::CreateTcParseTable() const { static_cast(table_info.aux_entries.size()), aux_offset, schema_.default_instance_, - &internal::TcParser::ReflectionFallback}; + &internal::TcParser::ReflectionFallback +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE + , + nullptr +#endif // PROTOBUF_PREFETCH_PARSE_TABLE + }; +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE + // We'll prefetch `to_prefetch->to_prefetch` unconditionally to avoid + // branches. Here we don't know which field is the hottest, so set the pointer + // to itself to avoid nullptr. + res->to_prefetch = res; +#endif // PROTOBUF_PREFETCH_PARSE_TABLE // Now copy the rest of the payloads PopulateTcParseFastEntries(table_info, res->fast_entry(0)); @@ -3586,8 +3615,6 @@ struct MetadataOwner { std::vector > metadata_arrays_; }; -void AddDescriptors(const DescriptorTable* table); - void AssignDescriptorsImpl(const DescriptorTable* table, bool eager) { // Ensure the file descriptor is added to the pool. { @@ -3660,6 +3687,7 @@ void AddDescriptorsImpl(const DescriptorTable* table) { // Reflection refers to the default fields so make sure they are initialized. internal::InitProtobufDefaults(); internal::InitializeFileDescriptorDefaultInstances(); + internal::InitializeLazyExtensionSet(); // Ensure all dependent descriptors are registered to the generated descriptor // pool and message factory. @@ -3674,16 +3702,6 @@ void AddDescriptorsImpl(const DescriptorTable* table) { MessageFactory::InternalRegisterGeneratedFile(table); } -void AddDescriptors(const DescriptorTable* table) { - // AddDescriptors is not thread safe. Callers need to ensure calls are - // properly serialized. This function is only called pre-main by global - // descriptors and we can assume single threaded access or it's called - // by AssignDescriptorImpl which uses a mutex to sequence calls. - if (table->is_initialized) return; - table->is_initialized = true; - AddDescriptorsImpl(table); -} - } // namespace // Separate function because it needs to be a friend of @@ -3699,6 +3717,16 @@ void RegisterAllTypesInternal(const Metadata* file_level_metadata, int size) { namespace internal { +void AddDescriptors(const DescriptorTable* table) { + // AddDescriptors is not thread safe. Callers need to ensure calls are + // properly serialized. This function is only called pre-main by global + // descriptors and we can assume single threaded access or it's called + // by AssignDescriptorImpl which uses a mutex to sequence calls. + if (table->is_initialized) return; + table->is_initialized = true; + AddDescriptorsImpl(table); +} + Metadata AssignDescriptors(const DescriptorTable* (*table)(), absl::once_flag* once, const Metadata& metadata) { absl::call_once(*once, [=] { @@ -3789,6 +3817,24 @@ bool SplitFieldHasExtraIndirection(const FieldDescriptor* field) { return field->is_repeated(); } +const Message* GetPrototypeForWeakDescriptor(const DescriptorTable* table, + int index) { + // First, make sure we inject the surviving default instances. + InitProtobufDefaults(); + + // Now check if the table has it. If so, return it. + if (const auto* msg = table->default_instances[index]) { + return msg; + } + + // Fallback to dynamic messages. + // Register the dep and generate the prototype via the generated pool. + AssignDescriptors(table); + ABSL_CHECK(table->file_level_metadata[index].descriptor != nullptr); + return MessageFactory::generated_factory()->GetPrototype( + table->file_level_metadata[index].descriptor); +} + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index 1df00c3c13..7b4281357b 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h @@ -15,12 +15,13 @@ #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__ +#include +#include +#include #include -#include "google/protobuf/stubs/common.h" #include "absl/base/call_once.h" -#include "absl/base/casts.h" -#include "absl/strings/string_view.h" +#include "absl/log/absl_check.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/generated_enum_reflection.h" #include "google/protobuf/port.h" @@ -40,6 +41,10 @@ class MapValueRef; class MessageLayoutInspector; class Message; struct Metadata; + +namespace io { +class CodedOutputStream; +} } // namespace protobuf } // namespace google @@ -333,10 +338,17 @@ PROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8_t* base, PROTOBUF_EXPORT void InitializeFileDescriptorDefaultInstances(); +PROTOBUF_EXPORT void AddDescriptors(const DescriptorTable* table); + struct PROTOBUF_EXPORT AddDescriptorsRunner { explicit AddDescriptorsRunner(const DescriptorTable* table); }; +// Retrieves the existing prototype out of a descriptor table. +// If it doesn't exist, asks the generated message factory for one. +const Message* GetPrototypeForWeakDescriptor(const DescriptorTable* table, + int index); + struct DenseEnumCacheInfo { std::atomic cache; int min_val; diff --git a/src/google/protobuf/generated_message_tctable_decl.h b/src/google/protobuf/generated_message_tctable_decl.h index 629cfb7293..72b703b857 100644 --- a/src/google/protobuf/generated_message_tctable_decl.h +++ b/src/google/protobuf/generated_message_tctable_decl.h @@ -18,6 +18,7 @@ #include #include +#include "absl/types/span.h" #include "google/protobuf/message_lite.h" #include "google/protobuf/parse_context.h" @@ -237,7 +238,7 @@ constexpr MapTypeCard MakeMapTypeCard(WireFormatLite::FieldType type) { case WireFormatLite::TYPE_GROUP: default: - PROTOBUF_ASSUME(false); + Unreachable(); } } @@ -284,18 +285,30 @@ struct alignas(uint64_t) TcParseTableBase { // Handler for fields which are not handled by table dispatch. TailCallParseFunc fallback; + // A sub message's table to be prefetched. +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE + const TcParseTableBase* to_prefetch; +#endif // PROTOBUF_PREFETCH_PARSE_TABLE + // This constructor exactly follows the field layout, so it's technically // not necessary. However, it makes it much much easier to add or re-arrange // fields, because it can be overloaded with an additional constructor, // temporarily allowing both old and new protocol buffer headers to be // compiled. - constexpr TcParseTableBase( - uint16_t has_bits_offset, uint16_t extension_offset, - uint32_t max_field_number, uint8_t fast_idx_mask, - uint16_t lookup_table_offset, uint32_t skipmap32, - uint32_t field_entries_offset, uint16_t num_field_entries, - uint16_t num_aux_entries, uint32_t aux_offset, - const MessageLite* default_instance, TailCallParseFunc fallback) + constexpr TcParseTableBase(uint16_t has_bits_offset, + uint16_t extension_offset, + uint32_t max_field_number, uint8_t fast_idx_mask, + uint16_t lookup_table_offset, uint32_t skipmap32, + uint32_t field_entries_offset, + uint16_t num_field_entries, + uint16_t num_aux_entries, uint32_t aux_offset, + const MessageLite* default_instance, + TailCallParseFunc fallback +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE + , + const TcParseTableBase* to_prefetch +#endif // PROTOBUF_PREFETCH_PARSE_TABLE + ) : has_bits_offset(has_bits_offset), extension_offset(extension_offset), max_field_number(max_field_number), @@ -307,7 +320,13 @@ struct alignas(uint64_t) TcParseTableBase { num_aux_entries(num_aux_entries), aux_offset(aux_offset), default_instance(default_instance), - fallback(fallback) {} + fallback(fallback) +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE + , + to_prefetch(to_prefetch) +#endif // PROTOBUF_PREFETCH_PARSE_TABLE + { + } // Table entry for fast-path tailcall dispatch handling. struct FastFieldEntry { @@ -375,6 +394,9 @@ struct alignas(uint64_t) TcParseTableBase { return reinterpret_cast( reinterpret_cast(this) + field_entries_offset); } + absl::Span field_entries() const { + return {field_entries_begin(), num_field_entries}; + } FieldEntry* field_entries_begin() { return reinterpret_cast(reinterpret_cast(this) + field_entries_offset); diff --git a/src/google/protobuf/generated_message_tctable_gen.cc b/src/google/protobuf/generated_message_tctable_gen.cc index 7c1736d63e..b421a355b3 100644 --- a/src/google/protobuf/generated_message_tctable_gen.cc +++ b/src/google/protobuf/generated_message_tctable_gen.cc @@ -8,6 +8,7 @@ #include "google/protobuf/generated_message_tctable_gen.h" #include +#include #include #include #include @@ -411,13 +412,7 @@ std::vector SplitFastFieldsForSize( // We only need field names for reporting UTF-8 parsing errors, so we only // emit them for string fields with Utf8 transform specified. bool NeedsFieldNameForTable(const FieldDescriptor* field, bool is_lite) { - if (cpp::GetUtf8CheckMode(field, is_lite) == cpp::Utf8CheckMode::kNone) - return false; - return field->type() == FieldDescriptor::TYPE_STRING || - (field->is_map() && (field->message_type()->map_key()->type() == - FieldDescriptor::TYPE_STRING || - field->message_type()->map_value()->type() == - FieldDescriptor::TYPE_STRING)); + return cpp::GetUtf8CheckMode(field, is_lite) != cpp::Utf8CheckMode::kNone; } absl::string_view FieldNameForTable( @@ -712,7 +707,7 @@ uint16_t MakeTypeCardForField( } break; default: - PROTOBUF_ASSUME(false); + Unreachable(); } } @@ -756,6 +751,35 @@ TailCallTableInfo::TailCallTableInfo( } } + auto is_non_cold = [](PerFieldOptions options) { + return options.presence_probability >= 0.005; + }; + size_t num_non_cold_subtables = 0; + if (message_options.should_profile_driven_cluster_aux_subtable) { + // We found that clustering non-cold subtables to the top of aux_entries + // achieves the best load tests results than other strategies (e.g., + // clustering all non-cold entries). + auto is_non_cold_subtable = [&](const FieldDescriptor* field) { + auto options = option_provider.GetForField(field); + // In the following code where we assign kSubTable to aux entries, only + // the following typed fields are supported. + return (field->type() == FieldDescriptor::TYPE_MESSAGE || + field->type() == FieldDescriptor::TYPE_GROUP) && + !field->is_map() && !HasLazyRep(field, options) && + !options.is_implicitly_weak && options.use_direct_tcparser_table && + is_non_cold(options); + }; + for (const FieldDescriptor* field : ordered_fields) { + if (is_non_cold_subtable(field)) { + num_non_cold_subtables++; + } + } + } + + size_t subtable_aux_idx_begin = aux_entries.size(); + size_t subtable_aux_idx = aux_entries.size(); + aux_entries.resize(aux_entries.size() + num_non_cold_subtables); + // Fill in mini table entries. for (const FieldDescriptor* field : ordered_fields) { auto options = option_provider.GetForField(field); @@ -797,12 +821,18 @@ TailCallTableInfo::TailCallTableInfo( TcParseTableBase::FieldEntry::kNoAuxIdx; } } else { - field_entries.back().aux_idx = aux_entries.size(); - aux_entries.push_back({options.is_implicitly_weak ? kSubMessageWeak - : options.use_direct_tcparser_table - ? kSubTable - : kSubMessage, - {field}}); + AuxType type = options.is_implicitly_weak ? kSubMessageWeak + : options.use_direct_tcparser_table ? kSubTable + : kSubMessage; + if (message_options.should_profile_driven_cluster_aux_subtable && + type == kSubTable && is_non_cold(options)) { + aux_entries[subtable_aux_idx] = {type, {field}}; + field_entries.back().aux_idx = subtable_aux_idx; + ++subtable_aux_idx; + } else { + field_entries.back().aux_idx = aux_entries.size(); + aux_entries.push_back({type, {field}}); + } } } else if (field->type() == FieldDescriptor::TYPE_ENUM && !cpp::HasPreservingUnknownEnumSemantics(field)) { @@ -845,6 +875,8 @@ TailCallTableInfo::TailCallTableInfo( entry.inlined_string_idx = idx; } } + ABSL_CHECK_EQ(subtable_aux_idx - subtable_aux_idx_begin, + num_non_cold_subtables); table_size_log2 = 0; // fallback value int num_fast_fields = -1; diff --git a/src/google/protobuf/generated_message_tctable_gen.h b/src/google/protobuf/generated_message_tctable_gen.h index bf202712a4..514f590a57 100644 --- a/src/google/protobuf/generated_message_tctable_gen.h +++ b/src/google/protobuf/generated_message_tctable_gen.h @@ -38,6 +38,8 @@ struct PROTOBUF_EXPORT TailCallTableInfo { struct MessageOptions { bool is_lite; bool uses_codegen; + // TODO: remove this after A/B test is done. + bool should_profile_driven_cluster_aux_subtable; }; struct PerFieldOptions { // For presence awareness (e.g. PDProto). diff --git a/src/google/protobuf/generated_message_tctable_impl.h b/src/google/protobuf/generated_message_tctable_impl.h index 42a56084b3..fb111e34fe 100644 --- a/src/google/protobuf/generated_message_tctable_impl.h +++ b/src/google/protobuf/generated_message_tctable_impl.h @@ -943,6 +943,10 @@ inline PROTOBUF_ALWAYS_INLINE const char* TcParser::ToParseLoop( return ptr; } +// Prints the type card as or of labels, using known higher level labels. +// Used for code generation, but also useful for debugging. +PROTOBUF_EXPORT std::string TypeCardToString(uint16_t type_card); + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/generated_message_tctable_lite.cc b/src/google/protobuf/generated_message_tctable_lite.cc index bf5a97b7a5..ed09b87f3c 100644 --- a/src/google/protobuf/generated_message_tctable_lite.cc +++ b/src/google/protobuf/generated_message_tctable_lite.cc @@ -18,6 +18,7 @@ #include "absl/log/absl_check.h" #include "absl/log/absl_log.h" #include "absl/numeric/bits.h" +#include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" #include "google/protobuf/generated_message_tctable_decl.h" #include "google/protobuf/generated_message_tctable_impl.h" @@ -26,6 +27,7 @@ #include "google/protobuf/map.h" #include "google/protobuf/message_lite.h" #include "google/protobuf/parse_context.h" +#include "google/protobuf/port.h" #include "google/protobuf/repeated_field.h" #include "google/protobuf/repeated_ptr_field.h" #include "google/protobuf/varint_shuffle.h" @@ -470,8 +472,7 @@ inline PROTOBUF_ALWAYS_INLINE const char* TcParser::RepeatedParseMessageAuxImpl( aux_is_table ? aux.table->default_instance : aux.message_default(); do { ptr += sizeof(TagType); - MessageLite* submsg = - field.Add>(default_instance); + MessageLite* submsg = field.AddMessage(default_instance); if (aux_is_table) { if (group_coding) { ptr = ctx->ParseGroup(submsg, ptr, @@ -2013,14 +2014,14 @@ PROTOBUF_NOINLINE const char* TcParser::MpRepeatedVarint( is_split, uint32_t, (is_split ? 0 : field_layout::kTvRange)>( PROTOBUF_TC_PARAM_PASS); default: - PROTOBUF_ASSUME(false); + Unreachable(); } case field_layout::kRep8Bits >> field_layout::kRepShift: PROTOBUF_MUSTTAIL return MpRepeatedVarintT( PROTOBUF_TC_PARAM_PASS); default: - PROTOBUF_ASSUME(false); + Unreachable(); return nullptr; // To silence -Werror=return-type in some toolchains } } @@ -2110,14 +2111,14 @@ PROTOBUF_NOINLINE const char* TcParser::MpPackedVarint(PROTOBUF_TC_PARAM_DECL) { is_split, uint32_t, (is_split ? 0 : field_layout::kTvRange)>( PROTOBUF_TC_PARAM_PASS); default: - PROTOBUF_ASSUME(false); + Unreachable(); } case field_layout::kRep8Bits >> field_layout::kRepShift: PROTOBUF_MUSTTAIL return MpPackedVarintT( PROTOBUF_TC_PARAM_PASS); default: - PROTOBUF_ASSUME(false); + Unreachable(); return nullptr; // To silence -Werror=return-type in some toolchains } } @@ -2216,7 +2217,7 @@ PROTOBUF_NOINLINE const char* TcParser::MpString(PROTOBUF_TC_PARAM_DECL) { } default: - PROTOBUF_ASSUME(false); + Unreachable(); } if (PROTOBUF_PREDICT_FALSE(ptr == nullptr || !is_valid)) { @@ -2426,8 +2427,7 @@ const char* TcParser::MpRepeatedMessageOrGroup(PROTOBUF_TC_PARAM_DECL) { const char* ptr2 = ptr; uint32_t next_tag; do { - MessageLite* value = - field.template Add>(default_instance); + MessageLite* value = field.AddMessage(default_instance); ptr = is_group ? ctx->ParseGroup(value, ptr2, decoded_tag, inner_table) : ctx->ParseMessage(value, ptr2, inner_table); @@ -2448,8 +2448,7 @@ const char* TcParser::MpRepeatedMessageOrGroup(PROTOBUF_TC_PARAM_DECL) { const char* ptr2 = ptr; uint32_t next_tag; do { - MessageLite* value = - field.template Add>(default_instance); + MessageLite* value = field.AddMessage(default_instance); ptr = is_group ? ctx->ParseGroup(value, ptr2, decoded_tag) : ctx->ParseMessage(value, ptr2); if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) goto error; @@ -2505,7 +2504,7 @@ static void SerializeMapKey(const NodeBase* node, MapTypeCard type_card, } break; default: - PROTOBUF_ASSUME(false); + Unreachable(); } break; case WireFormatLite::WIRETYPE_FIXED32: @@ -2524,7 +2523,7 @@ static void SerializeMapKey(const NodeBase* node, MapTypeCard type_card, &coded_output); break; default: - PROTOBUF_ASSUME(false); + Unreachable(); } } @@ -2569,7 +2568,7 @@ PROTOBUF_ALWAYS_INLINE inline void TcParser::InitializeMapNodeEntry( aux[1].create_in_arena(map.arena(), reinterpret_cast(obj)); break; default: - PROTOBUF_ASSUME(false); + Unreachable(); } } @@ -2663,7 +2662,7 @@ const char* TcParser::ParseOneMapEntry( memcpy(obj, &tmp, sizeof(tmp)); continue; default: - PROTOBUF_ASSUME(false); + Unreachable(); } case WFL::WIRETYPE_FIXED32: ptr = ReadFixed(obj, ptr); @@ -2699,7 +2698,7 @@ const char* TcParser::ParseOneMapEntry( continue; } default: - PROTOBUF_ASSUME(false); + Unreachable(); } } return ptr; @@ -2774,7 +2773,7 @@ PROTOBUF_NOINLINE const char* TcParser::MpMap(PROTOBUF_TC_PARAM_DECL) { static_cast::KeyNode*>(node)); break; default: - PROTOBUF_ASSUME(false); + Unreachable(); } } } @@ -2803,6 +2802,138 @@ PROTOBUF_NOINLINE const char* TcParser::MpMap(PROTOBUF_TC_PARAM_DECL) { PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_NO_DATA_PASS); } +std::string TypeCardToString(uint16_t type_card) { + // In here we convert the runtime value of entry.type_card back into a + // sequence of literal enum labels. We use the mnenonic labels for nicer + // codegen. + namespace fl = internal::field_layout; + const int rep_index = (type_card & fl::kRepMask) >> fl::kRepShift; + const int tv_index = (type_card & fl::kTvMask) >> fl::kTvShift; + + static constexpr const char* kFieldCardNames[] = {"Singular", "Optional", + "Repeated", "Oneof"}; + static_assert((fl::kFcSingular >> fl::kFcShift) == 0, ""); + static_assert((fl::kFcOptional >> fl::kFcShift) == 1, ""); + static_assert((fl::kFcRepeated >> fl::kFcShift) == 2, ""); + static_assert((fl::kFcOneof >> fl::kFcShift) == 3, ""); + + std::string out; + + absl::StrAppend(&out, "::_fl::kFc", + kFieldCardNames[(type_card & fl::kFcMask) >> fl::kFcShift]); + +#define PROTOBUF_INTERNAL_TYPE_CARD_CASE(x) \ + case fl::k##x: \ + absl::StrAppend(&out, " | ::_fl::k" #x); \ + break + + switch (type_card & fl::kFkMask) { + case fl::kFkString: { + switch (type_card & ~fl::kFcMask & ~fl::kRepMask & ~fl::kSplitMask) { + PROTOBUF_INTERNAL_TYPE_CARD_CASE(Bytes); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(RawString); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(Utf8String); + default: + ABSL_LOG(FATAL) << "Unknown type_card: 0x" << type_card; + } + + static constexpr const char* kRepNames[] = {"AString", "IString", "Cord", + "SPiece", "SString"}; + static_assert((fl::kRepAString >> fl::kRepShift) == 0, ""); + static_assert((fl::kRepIString >> fl::kRepShift) == 1, ""); + static_assert((fl::kRepCord >> fl::kRepShift) == 2, ""); + static_assert((fl::kRepSPiece >> fl::kRepShift) == 3, ""); + static_assert((fl::kRepSString >> fl::kRepShift) == 4, ""); + + absl::StrAppend(&out, " | ::_fl::kRep", kRepNames[rep_index]); + break; + } + + case fl::kFkMessage: { + absl::StrAppend(&out, " | ::_fl::kMessage"); + + static constexpr const char* kRepNames[] = {nullptr, "Group", "Lazy"}; + static_assert((fl::kRepGroup >> fl::kRepShift) == 1, ""); + static_assert((fl::kRepLazy >> fl::kRepShift) == 2, ""); + + if (auto* rep = kRepNames[rep_index]) { + absl::StrAppend(&out, " | ::_fl::kRep", rep); + } + + static constexpr const char* kXFormNames[2][4] = { + {nullptr, "Default", "Table", "WeakPtr"}, {nullptr, "Eager", "Lazy"}}; + + static_assert((fl::kTvDefault >> fl::kTvShift) == 1, ""); + static_assert((fl::kTvTable >> fl::kTvShift) == 2, ""); + static_assert((fl::kTvWeakPtr >> fl::kTvShift) == 3, ""); + static_assert((fl::kTvEager >> fl::kTvShift) == 1, ""); + static_assert((fl::kTvLazy >> fl::kTvShift) == 2, ""); + + if (auto* xform = kXFormNames[rep_index == 2][tv_index]) { + absl::StrAppend(&out, " | ::_fl::kTv", xform); + } + break; + } + + case fl::kFkMap: + absl::StrAppend(&out, " | ::_fl::kMap"); + break; + + case fl::kFkNone: + break; + + case fl::kFkVarint: + case fl::kFkPackedVarint: + case fl::kFkFixed: + case fl::kFkPackedFixed: { + switch (type_card & ~fl::kFcMask & ~fl::kSplitMask) { + PROTOBUF_INTERNAL_TYPE_CARD_CASE(Bool); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(Fixed32); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(UInt32); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(SFixed32); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(Int32); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(SInt32); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(Float); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(Enum); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(EnumRange); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(OpenEnum); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(Fixed64); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(UInt64); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(SFixed64); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(Int64); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(SInt64); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(Double); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedBool); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedFixed32); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedUInt32); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedSFixed32); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedInt32); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedSInt32); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedFloat); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedEnum); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedEnumRange); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedOpenEnum); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedFixed64); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedUInt64); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedSFixed64); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedInt64); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedSInt64); + PROTOBUF_INTERNAL_TYPE_CARD_CASE(PackedDouble); + default: + ABSL_LOG(FATAL) << "Unknown type_card: 0x" << type_card; + } + } + } + + if (type_card & fl::kSplitMask) { + absl::StrAppend(&out, " | ::_fl::kSplitTrue"); + } + +#undef PROTOBUF_INTERNAL_TYPE_CARD_CASE + + return out; +} + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/generated_message_tctable_lite_test.cc b/src/google/protobuf/generated_message_tctable_lite_test.cc index d037852b3d..136fea52a8 100644 --- a/src/google/protobuf/generated_message_tctable_lite_test.cc +++ b/src/google/protobuf/generated_message_tctable_lite_test.cc @@ -14,12 +14,18 @@ #include "google/protobuf/unittest.pb.h" #include "google/protobuf/wire_format_lite.h" + +// clang-format off +#include "google/protobuf/port_def.inc" +// clang-format on + namespace google { namespace protobuf { namespace internal { namespace { +using ::testing::ElementsAreArray; using ::testing::Eq; using ::testing::Not; using ::testing::Optional; @@ -82,6 +88,9 @@ TEST(FastVarints, NameHere) { offsetof(decltype(parse_table), field_names), // no aux_entries nullptr, // default instance FastParserGaveUp, // fallback +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE + nullptr, // to_prefetch +#endif // PROTOBUF_PREFETCH_PARSE_TABLE }, // Fast Table: {{ @@ -273,6 +282,9 @@ TEST(IsEntryForFieldNumTest, Matcher) { 0, 0, // num_aux_entries, aux_offset, nullptr, // default instance nullptr, // fallback function +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE + nullptr, // to_prefetch +#endif // PROTOBUF_PREFETCH_PARSE_TABLE }}; // clang-format on int table_field_numbers[] = {1, 2, 3}; @@ -341,6 +353,9 @@ TEST_F(FindFieldEntryTest, SequentialFieldRange) { 0, 0, // num_aux_entries, aux_offset, nullptr, // default instance {}, // fallback function +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE + nullptr, // to_prefetch +#endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {}, // fast_entries // field_lookup_table for 2, 3, 4, 5, 111: @@ -381,6 +396,9 @@ TEST_F(FindFieldEntryTest, SmallScanRange) { 0, 0, // num_aux_entries, aux_offset, nullptr, // default instance {}, // fallback function +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE + nullptr, // to_prefetch +#endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {}, // fast_entries // field_lookup_table for 1, 3, 4, 5, 7, 111: @@ -429,6 +447,9 @@ TEST_F(FindFieldEntryTest, BinarySearchRange) { 0, 0, // num_aux_entries, aux_offset, nullptr, // default instance {}, // fallback function +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE + nullptr, // to_prefetch +#endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {}, // fast_entries // field_lookup_table for 1, 3, 4, 5, 6, 8, 9, 11, 12, 70 @@ -474,6 +495,9 @@ TEST_F(FindFieldEntryTest, OutOfRange) { offsetof(decltype(table), field_names), // no aux_entries nullptr, // default instance {}, // fallback function +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE + nullptr, // to_prefetch +#endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {}, // fast_entries {{// field lookup table @@ -524,6 +548,9 @@ TEST_F(FindFieldEntryTest, EmptyMessage) { offsetof(TableType, field_names), nullptr, // default instance nullptr, // fallback function +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE + nullptr, // to_prefetch +#endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {}, // fast_entries {{// empty field lookup table @@ -574,6 +601,9 @@ const TcParseTable<5, 134, 5, 2176, 55> test_all_types_table = { offsetof(decltype(test_all_types_table), aux_entries), nullptr, // default instance nullptr, // fallback function +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE + nullptr, // to_prefetch +#endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // tail-call table @@ -831,7 +861,7 @@ TEST(GeneratedMessageTctableLiteTest, PackedEnumSmallRange) { // This test checks that the parser doesn't overflow an int32 when computing the // array's new length. TEST(GeneratedMessageTctableLiteTest, PackedEnumSmallRangeLargeSize) { -#ifdef ABSL_HAVE_MEMORY_SANITIZER +#ifdef PROTOBUF_MSAN // This test attempts to allocate 8GB of memory, which OOMs MSAN. return; #endif @@ -899,6 +929,7 @@ TEST(GeneratedMessageTctableLiteTest, EXPECT_LE(proto.vals().Capacity(), 2048); } + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc index 4893ca80b9..1bad594727 100644 --- a/src/google/protobuf/generated_message_util.cc +++ b/src/google/protobuf/generated_message_util.cc @@ -21,6 +21,7 @@ #include "google/protobuf/io/zero_copy_stream_impl_lite.h" #include "google/protobuf/message_lite.h" #include "google/protobuf/metadata_lite.h" +#include "google/protobuf/port.h" #include "google/protobuf/repeated_field.h" #include "google/protobuf/wire_format_lite.h" @@ -48,10 +49,32 @@ PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT const EmptyCord empty_cord_; +#if defined(PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED) +extern "C" { +// We add a single dummy writer to guarantee the section is never empty. +WeakDefaultWriter dummy_writer + __attribute__((section("pb_defaults"))) = {&dummy_writer.source, nullptr}; +// When using --descriptor_implicit_weak_messages we expect the writer objects +// to live in the `pb_defaults` section. We load them all using the +// __start/__end symbols provided by the linker. +extern const WeakDefaultWriter __start_pb_defaults; +extern const WeakDefaultWriter __stop_pb_defaults; +} +static void InitWeakDefaults() { + StrongPointer(&dummy_writer); // force link the dummy writer. + for (auto it = &__start_pb_defaults; it != &__stop_pb_defaults; ++it) { + *it->destination = it->source; + } +} +#else +void InitWeakDefaults() {} +#endif + PROTOBUF_CONSTINIT std::atomic init_protobuf_defaults_state{false}; static bool InitProtobufDefaultsImpl() { fixed_address_empty_string.DefaultConstruct(); OnShutdownDestroyString(fixed_address_empty_string.get_mutable()); + InitWeakDefaults(); init_protobuf_defaults_state.store(true, std::memory_order_release); diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h index 72e66494b7..4c1258f128 100644 --- a/src/google/protobuf/generated_message_util.h +++ b/src/google/protobuf/generated_message_util.h @@ -316,6 +316,13 @@ class MapSorterPtr { std::unique_ptr items_; }; +// Single message link for implicit weak descriptor messages. +// The runtime will register all the instances that are linked in. +struct WeakDefaultWriter { + const Message** destination; + const Message* source; +}; + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/has_bits.h b/src/google/protobuf/has_bits.h index 72af335fcc..93cda15192 100644 --- a/src/google/protobuf/has_bits.h +++ b/src/google/protobuf/has_bits.h @@ -8,6 +8,9 @@ #ifndef GOOGLE_PROTOBUF_HAS_BITS_H__ #define GOOGLE_PROTOBUF_HAS_BITS_H__ +#include +#include +#include #include #include "google/protobuf/stubs/common.h" @@ -54,7 +57,12 @@ class HasBits { } void Or(const HasBits& rhs) { - for (int i = 0; i < doublewords; i++) has_bits_[i] |= rhs.has_bits_[i]; + for (int i = 0; (i + 1) < doublewords; i += 2) { + Write64B(Read64B(i) | rhs.Read64B(i), i); + } + if ((doublewords % 2) != 0) { + has_bits_[doublewords - 1] |= rhs.has_bits_[doublewords - 1]; + } } bool empty() const; @@ -75,6 +83,16 @@ class HasBits { } } + uint64_t Read64B(int index) const { + uint64_t v; + memcpy(&v, has_bits_ + index, sizeof(v)); + return v; + } + + void Write64B(uint64_t v, int index) { + memcpy(has_bits_ + index, &v, sizeof(v)); + } + uint32_t has_bits_[doublewords]; }; diff --git a/src/google/protobuf/implicit_weak_message.h b/src/google/protobuf/implicit_weak_message.h index 0428d9eb32..ebd78f1a56 100644 --- a/src/google/protobuf/implicit_weak_message.h +++ b/src/google/protobuf/implicit_weak_message.h @@ -61,7 +61,14 @@ class PROTOBUF_EXPORT ImplicitWeakMessage : public MessageLite { ClassData header; char name[1]; }; - static constexpr Data data = {{}, ""}; + static constexpr Data data = { + { + nullptr, // merge_impl + nullptr, // on_demand_register_arena_dtor + nullptr, // descriptor_methods + PROTOBUF_FIELD_OFFSET(ImplicitWeakMessage, cached_size_), + }, + ""}; return &data.header; } @@ -84,7 +91,9 @@ class PROTOBUF_EXPORT ImplicitWeakMessage : public MessageLite { const char* _InternalParse(const char* ptr, ParseContext* ctx) final; size_t ByteSizeLong() const override { - return data_ == nullptr ? 0 : data_->size(); + size_t size = data_ == nullptr ? 0 : data_->size(); + cached_size_.Set(internal::ToCachedSize(size)); + return size; } uint8_t* _InternalSerialize(uint8_t* target, @@ -103,6 +112,7 @@ class PROTOBUF_EXPORT ImplicitWeakMessage : public MessageLite { // the default instance can be constant-initialized. In the const methods, we // have to handle the possibility of data_ being null. std::string* data_; + mutable google::protobuf::internal::CachedSize cached_size_{}; }; struct ImplicitWeakMessageDefaultType; @@ -157,7 +167,11 @@ struct WeakRepeatedPtrField { // TODO: make this constructor private explicit WeakRepeatedPtrField(Arena* arena) : weak(arena) {} - ~WeakRepeatedPtrField() { weak.template Destroy(); } + ~WeakRepeatedPtrField() { + if (weak.NeedsDestroy()) { + weak.DestroyProtos(); + } + } typedef internal::RepeatedPtrIterator iterator; typedef internal::RepeatedPtrIterator const_iterator; @@ -187,9 +201,6 @@ struct WeakRepeatedPtrField { return const_pointer_iterator(base().raw_data() + base().size()); } - MessageLite* AddWeak(const MessageLite* prototype) { - return base().AddWeak(prototype); - } T* Add() { return weak.Add(); } void Clear() { base().template Clear(); } void MergeFrom(const WeakRepeatedPtrField& other) { diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h index ecb0f2ec57..97d62e4900 100644 --- a/src/google/protobuf/io/coded_stream.h +++ b/src/google/protobuf/io/coded_stream.h @@ -91,6 +91,7 @@ #include #include #include +#include #include #include #include @@ -522,6 +523,9 @@ class PROTOBUF_EXPORT CodedInputStream { // See EnableAliasing(). bool aliasing_enabled_; + // If true, set eager parsing mode to override lazy fields. + bool force_eager_parsing_; + // Limits Limit current_limit_; // if position = -1, no limit is applied @@ -1553,6 +1557,7 @@ inline CodedInputStream::CodedInputStream(ZeroCopyInputStream* input) last_tag_(0), legitimate_message_end_(false), aliasing_enabled_(false), + force_eager_parsing_(false), current_limit_(std::numeric_limits::max()), buffer_size_after_limit_(0), total_bytes_limit_(kDefaultTotalBytesLimit), @@ -1573,6 +1578,7 @@ inline CodedInputStream::CodedInputStream(const uint8_t* buffer, int size) last_tag_(0), legitimate_message_end_(false), aliasing_enabled_(false), + force_eager_parsing_(false), current_limit_(size), buffer_size_after_limit_(0), total_bytes_limit_(kDefaultTotalBytesLimit), diff --git a/src/google/protobuf/json/BUILD.bazel b/src/google/protobuf/json/BUILD.bazel index f45c4fab2b..ccc369b2b9 100644 --- a/src/google/protobuf/json/BUILD.bazel +++ b/src/google/protobuf/json/BUILD.bazel @@ -96,6 +96,7 @@ cc_library( "//src/google/protobuf:protobuf_lite", "//src/google/protobuf/io", "//src/google/protobuf/util:type_resolver_util", + "//third_party/utf8_range:utf8_validity", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/status", "@com_google_absl//absl/strings", @@ -103,7 +104,6 @@ cc_library( "@com_google_absl//absl/types:optional", "@com_google_absl//absl/types:span", "@com_google_absl//absl/types:variant", - "@utf8_range//:utf8_validity", ], ) diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index e84ca694dd..4ea42241dd 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -454,18 +454,6 @@ size_t SpaceUsedInValues(const Map* map) { return size; } -// Multiply two numbers where overflow is expected. -template -N MultiplyWithOverflow(N a, N b) { -#if defined(PROTOBUF_HAS_BUILTIN_MUL_OVERFLOW) - N res; - (void)__builtin_mul_overflow(a, b, &res); - return res; -#else - return a * b; -#endif -} - inline size_t SpaceUsedInValues(const void*) { return 0; } class UntypedMapBase; @@ -536,7 +524,8 @@ class PROTOBUF_EXPORT UntypedMapBase { UntypedMapBase& operator=(const UntypedMapBase&) = delete; protected: - enum { kMinTableSize = 8 }; + // 16 bytes is the minimum useful size for the array cache in the arena. + enum { kMinTableSize = 16 / sizeof(void*) }; public: Arena* arena() const { return this->alloc_.arena(); } @@ -649,7 +638,11 @@ class PROTOBUF_EXPORT UntypedMapBase { } void DeleteTable(TableEntryPtr* table, map_index_t n) { - AllocFor(alloc_).deallocate(table, n); + if (auto* a = arena()) { + a->ReturnArrayMemory(table, n * sizeof(TableEntryPtr)); + } else { + internal::SizedDelete(table, n * sizeof(TableEntryPtr)); + } } NodeBase* DestroyTree(Tree* tree); @@ -664,13 +657,8 @@ class PROTOBUF_EXPORT UntypedMapBase { map_index_t BucketNumberFromHash(uint64_t h) const { // We xor the hash value against the random seed so that we effectively // have a random hash function. - h ^= seed_; - - // We use the multiplication method to determine the bucket number from - // the hash value. The constant kPhi (suggested by Knuth) is roughly - // (sqrt(5) - 1) / 2 * 2^64. - constexpr uint64_t kPhi = uint64_t{0x9e3779b97f4a7c15}; - return (MultiplyWithOverflow(kPhi, h) >> 32) & (num_buckets_ - 1); + // We use absl::Hash to do bit mixing for uniform bucket selection. + return absl::HashOf(h ^ seed_) & (num_buckets_ - 1); } TableEntryPtr* CreateEmptyTable(map_index_t n) { @@ -683,29 +671,29 @@ class PROTOBUF_EXPORT UntypedMapBase { // Return a randomish value. map_index_t Seed() const { - // We get a little bit of randomness from the address of the map. The - // lower bits are not very random, due to alignment, so we discard them - // and shift the higher bits into their place. - map_index_t s = reinterpret_cast(this) >> 4; + uint64_t s = 0; #if !defined(GOOGLE_PROTOBUF_NO_RDTSC) #if defined(__APPLE__) // Use a commpage-based fast time function on Apple environments (MacOS, // iOS, tvOS, watchOS, etc). - s += mach_absolute_time(); + s = mach_absolute_time(); #elif defined(__x86_64__) && defined(__GNUC__) uint32_t hi, lo; asm volatile("rdtsc" : "=a"(lo), "=d"(hi)); - s += ((static_cast(hi) << 32) | lo); + s = ((static_cast(hi) << 32) | lo); #elif defined(__aarch64__) && defined(__GNUC__) // There is no rdtsc on ARMv8. CNTVCT_EL0 is the virtual counter of the // system timer. It runs at a different frequency than the CPU's, but is // the best source of time-based entropy we get. uint64_t virtual_timer_value; asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value)); - s += virtual_timer_value; + s = virtual_timer_value; #endif #endif // !defined(GOOGLE_PROTOBUF_NO_RDTSC) - return s; + // Add entropy from the address of the map and the address of the table + // array. + return static_cast( + absl::HashOf(s, table_, static_cast(this))); } enum { @@ -988,6 +976,18 @@ class KeyMapBase : public UntypedMapBase { static_cast(node)->key()); } + // Have it a separate function for testing. + static size_type CalculateHiCutoff(size_type num_buckets) { + // We want the high cutoff to follow this rules: + // - When num_buckets_ == kGlobalEmptyTableSize, then make it 0 to force an + // allocation. + // - When num_buckets_ < 8, then make it num_buckets_ to avoid + // a reallocation. A large load factor is not that important on small + // tables and saves memory. + // - Otherwise, make it 75% of num_buckets_. + return num_buckets - num_buckets / 16 * 4 - num_buckets % 2; + } + // Returns whether it did resize. Currently this is only used when // num_elements_ increases, though it could be used in other situations. // It checks for load too low as well as load too high: because any number @@ -997,13 +997,12 @@ class KeyMapBase : public UntypedMapBase { // policy that sometimes we resize down as well as up, clients can easily // keep O(size()) = O(number of buckets) if they want that. bool ResizeIfLoadIsOutOfRange(size_type new_size) { - const size_type kMaxMapLoadTimes16 = 12; // controls RAM vs CPU tradeoff - const size_type hi_cutoff = num_buckets_ * kMaxMapLoadTimes16 / 16; + const size_type hi_cutoff = CalculateHiCutoff(num_buckets_); const size_type lo_cutoff = hi_cutoff / 4; // We don't care how many elements are in trees. If a lot are, // we may resize even though there are many empty buckets. In // practice, this seems fine. - if (PROTOBUF_PREDICT_FALSE(new_size >= hi_cutoff)) { + if (PROTOBUF_PREDICT_FALSE(new_size > hi_cutoff)) { if (num_buckets_ <= max_size() / 2) { Resize(num_buckets_ * 2); return true; diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h index 2163383aed..dead40ac02 100644 --- a/src/google/protobuf/map_entry.h +++ b/src/google/protobuf/map_entry.h @@ -44,6 +44,25 @@ namespace google { namespace protobuf { namespace internal { +// Base class to keep common fields and virtual function overrides. +class MapEntryBase : public Message { + protected: + using Message::Message; + + const ClassData* GetClassData() const final { + ABSL_CONST_INIT static const ClassData data = { + &MergeImpl, + nullptr, // on_demand_register_arena_dtor + &kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(MapEntryBase, _cached_size_), + }; + return &data; + } + + HasBits<1> _has_bits_{}; + mutable CachedSize _cached_size_{}; +}; + // MapEntry is the returned google::protobuf::Message when calling AddMessage of // google::protobuf::Reflection. In order to let it work with generated message // reflection, its in-memory type is the same as generated message with the same @@ -73,7 +92,7 @@ namespace internal { template -class MapEntry : public Message { +class MapEntry : public MapEntryBase { // Provide utilities to parse/serialize key/value. Provide utilities to // manipulate internal stored type. using KeyTypeHandler = MapTypeHandler; @@ -98,14 +117,12 @@ class MapEntry : public Message { public: constexpr MapEntry() : key_(KeyTypeHandler::Constinit()), - value_(ValueTypeHandler::Constinit()), - _has_bits_{} {} + value_(ValueTypeHandler::Constinit()) {} explicit MapEntry(Arena* arena) - : Message(arena), + : MapEntryBase(arena), key_(KeyTypeHandler::Constinit()), - value_(ValueTypeHandler::Constinit()), - _has_bits_{} {} + value_(ValueTypeHandler::Constinit()) {} MapEntry(const MapEntry&) = delete; MapEntry& operator=(const MapEntry&) = delete; @@ -122,12 +139,6 @@ class MapEntry : public Message { // accessors ====================================================== - inline const auto& key() const { - return KeyTypeHandler::GetExternalReference(key_); - } - inline const auto& value() const { - return ValueTypeHandler::DefaultIfNotInitialized(value_); - } inline auto* mutable_key() { _has_bits_[0] |= 0x00000001u; return KeyTypeHandler::EnsureMutable(&key_, GetArena()); @@ -136,7 +147,6 @@ class MapEntry : public Message { _has_bits_[0] |= 0x00000002u; return ValueTypeHandler::EnsureMutable(&value_, GetArena()); } - // TODO: These methods currently differ in behavior from the ones // implemented via reflection. This means that a MapEntry does not behave the // same as an equivalent object made via DynamicMessage. @@ -168,30 +178,10 @@ class MapEntry : public Message { return ptr; } - size_t ByteSizeLong() const final { - size_t size = 0; - size += kTagSize + static_cast(KeyTypeHandler::ByteSize(key())); - size += kTagSize + static_cast(ValueTypeHandler::ByteSize(value())); - _cached_size_.Set(ToCachedSize(size)); - return size; - } - - ::uint8_t* _InternalSerialize(::uint8_t* ptr, - io::EpsCopyOutputStream* stream) const final { - ptr = KeyTypeHandler::Write(kKeyFieldNumber, key(), ptr, stream); - return ValueTypeHandler::Write(kValueFieldNumber, value(), ptr, stream); - } - - bool IsInitialized() const final { - return ValueTypeHandler::IsInitialized(value_); - } - Message* New(Arena* arena) const final { return Arena::CreateMessage(arena); } - CachedSize* AccessCachedSize() const final { return &_cached_size_; } - protected: friend class google::protobuf::Arena; template _has_bits_; - mutable CachedSize _cached_size_; }; } // namespace internal diff --git a/src/google/protobuf/map_field.cc b/src/google/protobuf/map_field.cc index 0d70c65301..6496d715f8 100644 --- a/src/google/protobuf/map_field.cc +++ b/src/google/protobuf/map_field.cc @@ -38,7 +38,7 @@ VariantKey RealKeyToVariantKey::operator()(const MapKey& value) const { case FieldDescriptor::CPPTYPE_BOOL: return VariantKey(static_cast(value.GetBoolValue())); default: - ABSL_ASSUME(false); + Unreachable(); return VariantKey(uint64_t{}); } } @@ -246,7 +246,7 @@ void MapFieldBase::SyncRepeatedFieldWithMapNoLock() { reflection->SetBool(new_entry, key_des, map_key.GetBoolValue()); break; default: - PROTOBUF_ASSUME(false); + Unreachable(); } const MapValueRef& map_val = it.GetValueRef(); @@ -342,7 +342,7 @@ void MapFieldBase::SyncMapWithRepeatedFieldNoLock() { map_key.SetBoolValue(reflection->GetBool(elem, key_des)); break; default: - PROTOBUF_ASSUME(false); + Unreachable(); } MapValueRef map_val; diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index 8aa9e45fe3..b9d03c806f 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -436,7 +436,7 @@ class PROTOBUF_EXPORT MapFieldBase : public MapFieldBaseForParse { // thread calls either ConstAccess() or MutableAccess(), on the same // MapFieldBase-derived object, and there is no synchronization going // on between them, tsan will alert. -#if defined(__SANITIZE_THREAD__) || defined(THREAD_SANITIZER) +#if defined(PROTOBUF_TSAN) void ConstAccess() const { ABSL_CHECK_EQ(seq1_, seq2_); } void MutableAccess() { if (seq1_ & 1) { @@ -678,7 +678,7 @@ class MapField final : public TypeDefinedMapFieldBase { template -constexpr MapFieldBase::VTable +PROTOBUF_CONSTINIT const MapFieldBase::VTable MapField::kVTable = MapField::template MakeVTable(); diff --git a/src/google/protobuf/map_proto3_unittest.proto b/src/google/protobuf/map_proto3_unittest.proto index 1181b29988..29a3b367a2 100644 --- a/src/google/protobuf/map_proto3_unittest.proto +++ b/src/google/protobuf/map_proto3_unittest.proto @@ -21,3 +21,7 @@ message TestProto3BytesMap { map map_bytes = 1; map map_string = 2; } + +message TestI32StrMap { + map m_32_str = 1; +} diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index e09471a0ca..7e9a80df42 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -5,13 +5,21 @@ // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd +#include "google/protobuf/map.h" + #include +#include +#include +#include #include #include #include #include +#include +#include #include "absl/container/flat_hash_set.h" +#include "absl/strings/str_cat.h" #include "google/protobuf/arena_test_util.h" #include "google/protobuf/internal_visibility_for_testing.h" #include "google/protobuf/map_proto2_unittest.pb.h" @@ -54,7 +62,10 @@ struct is_internal_map_value_type : std::true_type {}; namespace { +using ::testing::AllOf; using ::testing::FieldsAre; +using ::testing::Ge; +using ::testing::Le; using ::testing::UnorderedElementsAre; @@ -160,6 +171,94 @@ TEST(MapTest, CopyConstructMessagesWithArena) { EXPECT_EQ(map1["2"].GetArena(), &arena); } +TEST(MapTest, AlwaysSerializesBothEntries) { + for (const Message* prototype : + {static_cast( + &protobuf_unittest::TestI32StrMap::default_instance()), + static_cast( + &proto3_unittest::TestI32StrMap::default_instance())}) { + const FieldDescriptor* map_field = + prototype->GetDescriptor()->FindFieldByName("m_32_str"); + const FieldDescriptor* map_key = map_field->message_type()->map_key(); + const FieldDescriptor* map_value = map_field->message_type()->map_value(); + for (bool add_key : {true, false}) { + for (bool add_value : {true, false}) { + std::unique_ptr message(prototype->New()); + Message* entry_message = + message->GetReflection()->AddMessage(message.get(), map_field); + // Add the fields, but leave them as the default to make it easier to + // match. + if (add_key) { + entry_message->GetReflection()->SetInt32(entry_message, map_key, 0); + } + if (add_value) { + entry_message->GetReflection()->SetString(entry_message, map_value, + ""); + } + ASSERT_EQ(4, entry_message->ByteSizeLong()); + EXPECT_EQ(entry_message->SerializeAsString(), + std::string({ + '\010', '\0', // key, VARINT, value=0 + '\022', '\0', // value, LEN, size=0 + })); + ASSERT_EQ(6, message->ByteSizeLong()); + EXPECT_EQ(message->SerializeAsString(), + std::string({ + '\012', '\04', // field=1, LEN, size=4 + '\010', '\0', // key, VARINT, value=0 + '\022', '\0', // value, LEN, size=0 + })); + } + } + } +} + +TEST(MapTest, LoadFactorCalculationWorks) { + // Three stages: + // - empty + // - small + // - large + + const auto calculate = MapTestPeer::CalculateHiCutoff; + // empty + EXPECT_EQ(calculate(kGlobalEmptyTableSize), 0); + + // small + EXPECT_EQ(calculate(2), 2); + EXPECT_EQ(calculate(4), 4); + EXPECT_EQ(calculate(8), 8); + + // large + for (int i = 16; i < 10000; i *= 2) { + EXPECT_EQ(calculate(i), .75 * i) << "i=" << i; + } +} + +TEST(MapTest, NaturalGrowthOnArenasReuseBlocks) { + Arena arena; + std::vector*> values; + + static constexpr int kNumFields = 100; + static constexpr int kNumElems = 1000; + for (int i = 0; i < kNumFields; ++i) { + values.push_back(Arena::CreateMessage>(&arena)); + auto& field = *values.back(); + for (int j = 0; j < kNumElems; ++j) { + field[j] = j; + } + } + + struct MockNode : internal::NodeBase { + std::pair v; + }; + size_t expected = + values.size() * (MapTestPeer::NumBuckets(*values[0]) * sizeof(void*) + + values[0]->size() * sizeof(MockNode)); + // Use a 2% slack for other overhead. If we were not reusing the blocks, the + // actual value would be ~2x the cost of the bucket array. + EXPECT_THAT(arena.SpaceUsed(), AllOf(Ge(expected), Le(1.02 * expected))); +} + // We changed the internal implementation to use a smaller size type, but the // public API will still use size_t to avoid changing the API. Test that. TEST(MapTest, SizeTypeIsSizeT) { diff --git a/src/google/protobuf/map_test.inc b/src/google/protobuf/map_test.inc index c1b0029878..cbd0f44618 100644 --- a/src/google/protobuf/map_test.inc +++ b/src/google/protobuf/map_test.inc @@ -182,6 +182,11 @@ struct MapTestPeer { return true; } + template + static size_t NumBuckets(T& map) { + return map.num_buckets_; + } + template static size_t BucketNumber(T& map, typename T::key_type key) { return map.BucketNumber(key); @@ -199,6 +204,10 @@ struct MapTestPeer { } return false; } + + static int CalculateHiCutoff(int num_buckets) { + return Map::CalculateHiCutoff(num_buckets); + } }; namespace { @@ -1276,7 +1285,7 @@ TEST_F(MapImplTest, CopyAssignMapIterator) { } TEST_F(MapImplTest, SpaceUsed) { - constexpr size_t kMinCap = 8; + constexpr size_t kMinCap = 16 / sizeof(void*); Map m; // An newly constructed map should have no space used. @@ -1286,15 +1295,11 @@ TEST_F(MapImplTest, SpaceUsed) { std::pair kv; }; - size_t capacity = kMinCap; for (int i = 0; i < 100; ++i) { m[i]; - static constexpr double kMaxLoadFactor = .75; - if (m.size() >= capacity * kMaxLoadFactor) { - capacity *= 2; - } EXPECT_EQ(m.SpaceUsedExcludingSelfLong(), - sizeof(void*) * capacity + m.size() * sizeof(IntIntNode)); + sizeof(void*) * MapTestPeer::NumBuckets(m) + + m.size() * sizeof(IntIntNode)); } // Test string, and non-scalar keys. @@ -1360,11 +1365,10 @@ void TestTransparent(const Key& key, const Key& miss_key) { const auto& cm = m; m.insert({"ABC", 1}); - - const auto abc_it = m.begin(); - m.insert({"DEF", 2}); + const auto abc_it = m.find("ABC"); + using testing::Pair; using testing::UnorderedElementsAre; diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h index 7475ab04a3..7429dae7de 100644 --- a/src/google/protobuf/map_type_handler.h +++ b/src/google/protobuf/map_type_handler.h @@ -93,16 +93,10 @@ class MapTypeHandler { uint8_t* ptr, io::EpsCopyOutputStream* stream); // Functions to manipulate data on memory. ======================== - static inline const Type& GetExternalReference(const Type* value); static inline void DeleteNoArena(const Type* x); static constexpr TypeOnMemory Constinit(); static inline Type* EnsureMutable(Type** value, Arena* arena); - // Return default instance if value is not initialized when calling const - // reference accessor. - static inline const Type& DefaultIfNotInitialized(const Type* value); - // Check if all required fields have values set. - static inline bool IsInitialized(Type* value); }; #define MAP_HANDLER(FieldType) \ @@ -126,12 +120,7 @@ class MapTypeHandler { static inline uint8_t* Write(int field, const MapEntryAccessorType& value, \ uint8_t* ptr, \ io::EpsCopyOutputStream* stream); \ - static inline const MapEntryAccessorType& GetExternalReference( \ - const TypeOnMemory& value); \ static inline void DeleteNoArena(const TypeOnMemory& x); \ - static inline const MapEntryAccessorType& DefaultIfNotInitialized( \ - const TypeOnMemory& value); \ - static inline bool IsInitialized(const TypeOnMemory& value); \ static void DeleteNoArena(TypeOnMemory& value); \ static constexpr TypeOnMemory Constinit(); \ static inline MapEntryAccessorType* EnsureMutable(TypeOnMemory* value, \ @@ -420,13 +409,6 @@ READ_METHOD(BOOL) // Definition for message handler -template -inline const Type& -MapTypeHandler::GetExternalReference( - const Type* value) { - return *value; -} - template void MapTypeHandler::DeleteNoArena( const Type* ptr) { @@ -448,29 +430,9 @@ inline Type* MapTypeHandler::EnsureMutable( return *value; } -template -inline const Type& -MapTypeHandler::DefaultIfNotInitialized( - const Type* value) { - return value != nullptr ? *value : *Type::internal_default_instance(); -} - -template -inline bool MapTypeHandler::IsInitialized( - Type* value) { - return value ? value->IsInitialized() : false; -} - // Definition for string/bytes handler #define STRING_OR_BYTES_HANDLER_FUNCTIONS(FieldType) \ - template \ - inline const typename MapTypeHandler::MapEntryAccessorType& \ - MapTypeHandler::GetExternalReference(const TypeOnMemory& value) { \ - return value.Get(); \ - } \ template \ void MapTypeHandler::DeleteNoArena( \ TypeOnMemory& value) { \ @@ -479,7 +441,7 @@ inline bool MapTypeHandler::IsInitialized( template \ constexpr auto \ MapTypeHandler::Constinit() \ - ->TypeOnMemory { \ + -> TypeOnMemory { \ return TypeOnMemory(&internal::fixed_address_empty_string, \ ConstantInitialized{}); \ } \ @@ -489,32 +451,12 @@ inline bool MapTypeHandler::IsInitialized( MapTypeHandler::EnsureMutable( \ TypeOnMemory* value, Arena* arena) { \ return value->Mutable(arena); \ - } \ - template \ - inline const typename MapTypeHandler::MapEntryAccessorType& \ - MapTypeHandler::DefaultIfNotInitialized(const TypeOnMemory& value) { \ - return value.Get(); \ - } \ - template \ - inline bool \ - MapTypeHandler::IsInitialized( \ - const TypeOnMemory& /* value */) { \ - return true; \ } STRING_OR_BYTES_HANDLER_FUNCTIONS(STRING) STRING_OR_BYTES_HANDLER_FUNCTIONS(BYTES) #undef STRING_OR_BYTES_HANDLER_FUNCTIONS #define PRIMITIVE_HANDLER_FUNCTIONS(FieldType) \ - template \ - inline const typename MapTypeHandler::MapEntryAccessorType& \ - MapTypeHandler::GetExternalReference(const TypeOnMemory& value) { \ - return value; \ - } \ template \ inline void MapTypeHandler::DeleteNoArena(TypeOnMemory& /* x */) {} \ @@ -530,19 +472,6 @@ STRING_OR_BYTES_HANDLER_FUNCTIONS(BYTES) MapTypeHandler::EnsureMutable( \ TypeOnMemory* value, Arena* /* arena */) { \ return value; \ - } \ - template \ - inline const typename MapTypeHandler::MapEntryAccessorType& \ - MapTypeHandler::DefaultIfNotInitialized(const TypeOnMemory& value) { \ - return value; \ - } \ - template \ - inline bool \ - MapTypeHandler::IsInitialized( \ - const TypeOnMemory& /* value */) { \ - return true; \ } PRIMITIVE_HANDLER_FUNCTIONS(INT64) PRIMITIVE_HANDLER_FUNCTIONS(UINT64) diff --git a/src/google/protobuf/map_unittest.proto b/src/google/protobuf/map_unittest.proto index 11be80836e..5a648d202f 100644 --- a/src/google/protobuf/map_unittest.proto +++ b/src/google/protobuf/map_unittest.proto @@ -101,3 +101,7 @@ message MessageContainingMapCalledEntry { message TestRecursiveMapMessage { map a = 1; } + +message TestI32StrMap { + map m_32_str = 1; +} diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index eb81694daf..91f770c838 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -22,8 +22,10 @@ #include "absl/strings/str_join.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" +#include "absl/types/optional.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" +#include "google/protobuf/dynamic_message.h" #include "google/protobuf/generated_message_reflection.h" #include "google/protobuf/generated_message_tctable_impl.h" #include "google/protobuf/generated_message_util.h" @@ -58,29 +60,18 @@ using internal::ReflectionOps; using internal::WireFormat; using internal::WireFormatLite; -void Message::MergeImpl(Message& to, const Message& from) { - ReflectionOps::Merge(from, &to); +void Message::MergeImpl(MessageLite& to, const MessageLite& from) { + ReflectionOps::Merge(DownCast(from), DownCast(&to)); } void Message::MergeFrom(const Message& from) { auto* class_to = GetClassData(); auto* class_from = from.GetClassData(); - auto* merge_to_from = class_to ? class_to->merge_to_from : nullptr; if (class_to == nullptr || class_to != class_from) { - merge_to_from = [](Message& to, const Message& from) { - ReflectionOps::Merge(from, &to); - }; + ReflectionOps::Merge(from, this); + } else { + class_to->merge_to_from(*this, from); } - merge_to_from(*this, from); -} - -const MessageLite::ClassData* Message::GetClassData() const { - static constexpr ClassData data = { - &MergeImpl, - nullptr, - &kDescriptorMethods, - }; - return &data; } void Message::CheckTypeAndMergeFrom(const MessageLite& other) { @@ -158,14 +149,7 @@ uint8_t* Message::_InternalSerialize(uint8_t* target, size_t Message::ByteSizeLong() const { size_t size = WireFormat::ByteSize(*this); - - auto* cached_size = AccessCachedSize(); - ABSL_CHECK(cached_size != nullptr) - << "Message class \"" << GetDescriptor()->full_name() - << "\" implements neither AccessCachedSize() nor ByteSizeLong(). " - "Must implement one or the other."; - cached_size->Set(internal::ToCachedSize(size)); - + AccessCachedSize().Set(internal::ToCachedSize(size)); return size; } @@ -188,7 +172,13 @@ size_t Message::MaybeComputeUnknownFieldsSize( } size_t Message::SpaceUsedLong() const { - return GetReflection()->SpaceUsedLong(*this); + auto* reflection = GetReflection(); + if (PROTOBUF_PREDICT_TRUE(reflection != nullptr)) { + return reflection->SpaceUsedLong(*this); + } + // The only case that does not have reflection is RawMessage. + return internal::DownCast(*this) + .SpaceUsedLong(); } static std::string GetTypeNameImpl(const MessageLite& msg) { @@ -230,15 +220,21 @@ class GeneratedMessageFactory final : public MessageFactory { void RegisterFile(const google::protobuf::internal::DescriptorTable* table); void RegisterType(const Descriptor* descriptor, const Message* prototype); + const Message* TryGetPrototype(const Descriptor* type); + // implements MessageFactory --------------------------------------- const Message* GetPrototype(const Descriptor* type) override; private: - const Message* FindInTypeMap(const Descriptor* type) + GeneratedMessageFactory() { + dropped_defaults_factory_.SetDelegateToGeneratedFactory(true); + } + + absl::optional FindInTypeMap(const Descriptor* type) ABSL_SHARED_LOCKS_REQUIRED(mutex_) { auto it = type_map_.find(type); - if (it == type_map_.end()) return nullptr; + if (it == type_map_.end()) return absl::nullopt; return it->second; } @@ -282,6 +278,7 @@ class GeneratedMessageFactory final : public MessageFactory { absl::flat_hash_set files_; + DynamicMessageFactory dropped_defaults_factory_; absl::Mutex mutex_; absl::flat_hash_map type_map_ @@ -319,10 +316,36 @@ void GeneratedMessageFactory::RegisterType(const Descriptor* descriptor, const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) { + const Message* result = TryGetPrototype(type); + if (result == nullptr && + type->file()->pool() == DescriptorPool::generated_pool()) { + // We registered this descriptor with a null pointer. + // In this case we need to create the prototype from the dynamic factory. + // We _must_ do this outside the lock because the dynamic factory will call + // back into the generated factory for cross linking. + result = dropped_defaults_factory_.GetPrototype(type); + + { + absl::WriterMutexLock lock(&mutex_); + // And update the main map to make the next lookup faster. + // We don't need to recheck here. Even if someone raced us here the result + // is the same, so we can just write it. + type_map_[type] = result; + } + } + + return result; +} + +const Message* GeneratedMessageFactory::TryGetPrototype( + const Descriptor* type) { + absl::optional result; { absl::ReaderMutexLock lock(&mutex_); - const Message* result = FindInTypeMap(type); - if (result != nullptr) return result; + result = FindInTypeMap(type); + if (result.has_value() && *result != nullptr) { + return *result; + } } // If the type is not in the generated pool, then we can't possibly handle @@ -339,27 +362,30 @@ const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) { return nullptr; } - absl::WriterMutexLock lock(&mutex_); + { + absl::WriterMutexLock lock(&mutex_); - // Check if another thread preempted us. - const Message* result = FindInTypeMap(type); - if (result == nullptr) { - // Nope. OK, register everything. - internal::RegisterFileLevelMetadata(registration_data); - // Should be here now. + // Check if another thread preempted us. result = FindInTypeMap(type); + if (!result.has_value()) { + // Nope. OK, register everything. + internal::RegisterFileLevelMetadata(registration_data); + // Should be here now. + result = FindInTypeMap(type); + ABSL_DCHECK(result.has_value()); + } } - if (result == nullptr) { - ABSL_DLOG(FATAL) << "Type appears to be in generated pool but wasn't " - << "registered: " << type->full_name(); - } - - return result; + return *result; } } // namespace +const Message* MessageFactory::TryGetGeneratedPrototype( + const Descriptor* type) { + return GeneratedMessageFactory::singleton()->TryGetPrototype(type); +} + MessageFactory* MessageFactory::generated_factory() { return GeneratedMessageFactory::singleton(); } diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 83ba793e93..d25c2d7815 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -87,18 +87,16 @@ #ifndef GOOGLE_PROTOBUF_MESSAGE_H__ #define GOOGLE_PROTOBUF_MESSAGE_H__ -#include +#include +#include #include #include #include -#include "google/protobuf/stubs/common.h" #include "absl/base/attributes.h" #include "absl/base/call_once.h" -#include "absl/base/casts.h" -#include "absl/functional/function_ref.h" +#include "google/protobuf/stubs/common.h" #include "absl/log/absl_check.h" -#include "absl/log/absl_log.h" #include "absl/strings/cord.h" #include "absl/strings/string_view.h" #include "google/protobuf/arena.h" @@ -135,6 +133,7 @@ class MapValueConstRef; class MapValueRef; class MapIterator; class MapReflectionTester; +class TextFormat; namespace internal { struct FuzzPeer; @@ -147,6 +146,7 @@ struct TailCallTableInfo; } // namespace internal class UnknownFieldSet; // unknown_field_set.h namespace io { +class EpsCopyOutputStream; // coded_stream.h class ZeroCopyInputStream; // zero_copy_stream.h class ZeroCopyOutputStream; // zero_copy_stream.h class CodedInputStream; // coded_stream.h @@ -232,7 +232,7 @@ PROTOBUF_EXPORT bool IsDescendant(Message& root, const Message& message); // the internal library are allowed to create subclasses. class PROTOBUF_EXPORT Message : public MessageLite { public: - constexpr Message() {} + constexpr Message() = default; Message(const Message&) = delete; Message& operator=(const Message&) = delete; @@ -257,7 +257,7 @@ class PROTOBUF_EXPORT Message : public MessageLite { // messages which will be merged. Repeated fields will be concatenated. // The given message must be of the same type as this message (i.e. the // exact same class). - virtual void MergeFrom(const Message& from); + void MergeFrom(const Message& from); // Verifies that IsInitialized() returns true. ABSL_CHECK-fails otherwise, // with a nice error message. @@ -286,8 +286,7 @@ class PROTOBUF_EXPORT Message : public MessageLite { void DiscardUnknownFields(); // Computes (an estimate of) the total number of bytes currently used for - // storing the message in memory. The default implementation calls the - // Reflection object's SpaceUsed() method. + // storing the message in memory. // // SpaceUsed() is noticeably slower than ByteSize(), as it is implemented // using reflection (rather than the generated code implementation for @@ -297,7 +296,7 @@ class PROTOBUF_EXPORT Message : public MessageLite { // Note: The precise value of this method should never be depended on, and can // change substantially due to internal details. In debug builds, this will // include a random fuzz factor to prevent these dependencies. - virtual size_t SpaceUsedLong() const; + size_t SpaceUsedLong() const; [[deprecated("Please use SpaceUsedLong() instead")]] int SpaceUsed() const { return internal::ToIntSize(SpaceUsedLong()); @@ -370,14 +369,10 @@ class PROTOBUF_EXPORT Message : public MessageLite { internal::CachedSize* cached_size) const; // Reflection based version for reflection based types. - static void MergeImpl(Message& to, const Message& from); + static void MergeImpl(MessageLite& to, const MessageLite& from); static const DescriptorMethods kDescriptorMethods; - // Default implementation using reflection. Avoids bloat in MapEntry. - // Generated types will make their own. - const ClassData* GetClassData() const override; - }; namespace internal { @@ -892,39 +887,6 @@ class PROTOBUF_EXPORT Reflection final { // Returns nullptr if no extension is known for this name or number. const FieldDescriptor* FindKnownExtensionByNumber(int number) const; - // Feature Flags ------------------------------------------------------------- - - // Does this message support storing arbitrary integer values in enum fields? - // If |true|, GetEnumValue/SetEnumValue and associated repeated-field versions - // take arbitrary integer values, and the legacy GetEnum() getter will - // dynamically create an EnumValueDescriptor for any integer value without - // one. If |false|, setting an unknown enum value via the integer-based - // setters results in undefined behavior (in practice, ABSL_DCHECK-fails). - // - // Generic code that uses reflection to handle messages with enum fields - // should check this flag before using the integer-based setter, and either - // downgrade to a compatible value or use the UnknownFieldSet if not. For - // example: - // - // int new_value = GetValueFromApplicationLogic(); - // if (reflection->SupportsUnknownEnumValues()) { - // reflection->SetEnumValue(message, field, new_value); - // } else { - // if (field_descriptor->enum_type()-> - // FindValueByNumber(new_value) != nullptr) { - // reflection->SetEnumValue(message, field, new_value); - // } else if (emit_unknown_enum_values) { - // reflection->MutableUnknownFields(message)->AddVarint( - // field->number(), new_value); - // } else { - // // convert value to a compatible/default value. - // new_value = CompatibleDowngrade(new_value); - // reflection->SetEnumValue(message, field, new_value); - // } - // } - ABSL_DEPRECATED("Use EnumDescriptor::is_closed instead.") - bool SupportsUnknownEnumValues() const; - // Returns the MessageFactory associated with this message. This can be // useful for determining if a message is a generated message or not, for // example: @@ -1015,6 +977,7 @@ class PROTOBUF_EXPORT Reflection final { return schema_.IsSplit(field); } + friend class google::protobuf::TextFormat; friend class FastReflectionBase; friend class FastReflectionMessageMutator; friend bool internal::IsDescendant(Message& root, const Message& message); @@ -1292,7 +1255,7 @@ class PROTOBUF_EXPORT Reflection final { // around GetPrototype for details class PROTOBUF_EXPORT MessageFactory { public: - inline MessageFactory() {} + inline MessageFactory() = default; MessageFactory(const MessageFactory&) = delete; MessageFactory& operator=(const MessageFactory&) = delete; virtual ~MessageFactory(); @@ -1350,6 +1313,10 @@ class PROTOBUF_EXPORT MessageFactory { static void InternalRegisterGeneratedMessage(const Descriptor* descriptor, const Message* prototype); + + private: + friend class DynamicMessageFactory; + static const Message* TryGetGeneratedPrototype(const Descriptor* type); }; #define DECLARE_GET_REPEATED_FIELD(TYPE) \ @@ -1392,6 +1359,7 @@ const T* DynamicCastToGenerated(const Message* from) { (void)unused; #if PROTOBUF_RTTI + internal::StrongReference(T::default_instance()); return dynamic_cast(from); #else bool ok = from != nullptr && @@ -1430,11 +1398,7 @@ T& DynamicCastToGenerated(Message& from) { // instance T and T is a type derived from base Message class. template const T* DownCastToGenerated(const Message* from) { - // Compile-time assert that T is a generated type that has a - // default_instance() accessor, but avoid actually calling it. - const T& (*get_default_instance)() = &T::default_instance; - (void)get_default_instance; - + internal::StrongReference(T::default_instance()); ABSL_DCHECK(DynamicCastToGenerated(from) == from) << "Cannot downcast " << from->GetTypeName() << " to " << T::default_instance().GetTypeName(); @@ -1573,6 +1537,12 @@ bool SplitFieldHasExtraIndirectionStatic(const FieldDescriptor* field) { return ret; } +class RawMessageBase : public Message { + public: + using Message::Message; + virtual size_t SpaceUsedLong() const = 0; +}; + } // namespace internal template diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index 12ee82f4ca..8b5e83c32a 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -83,13 +83,15 @@ std::string MessageLite::DebugString() const { return absl::StrCat("MessageLite at 0x", absl::Hex(this)); } -int MessageLite::GetCachedSize() const { - auto* cached_size = AccessCachedSize(); - if (PROTOBUF_PREDICT_FALSE(cached_size == nullptr)) return ByteSize(); - return cached_size->Get(); -} +int MessageLite::GetCachedSize() const { return AccessCachedSize().Get(); } -internal::CachedSize* MessageLite::AccessCachedSize() const { return nullptr; } +internal::CachedSize& MessageLite::AccessCachedSize() const { + auto* data = GetClassData(); + ABSL_DCHECK(data != nullptr); + ABSL_DCHECK(data->cached_size_offset != 0); + return *reinterpret_cast(const_cast( + reinterpret_cast(this) + data->cached_size_offset)); +} namespace { @@ -249,7 +251,7 @@ bool MessageLite::MergeFromImpl(io::CodedInputStream* input, if (PROTOBUF_PREDICT_FALSE(!ptr)) return false; ctx.BackUp(ptr); if (!ctx.EndedAtEndOfStream()) { - ABSL_DCHECK_NE(ctx.LastTag(), 1); // We can't end on a pushed limit. + ABSL_DCHECK_NE(ctx.LastTag(), 1u); // We can't end on a pushed limit. if (ctx.IsExceedingLimit(ptr)) return false; input->SetLastTag(ctx.LastTag()); } else { @@ -649,11 +651,6 @@ void GenericTypeHandler::Merge(const MessageLite& from, MessageLite* to) { to->CheckTypeAndMergeFrom(from); } -template <> -void GenericTypeHandler::Merge(const std::string& from, - std::string* to) { - *to = from; -} // Non-inline variants of std::string specializations for // various InternalMetadata routines. diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index cbece7c799..71eb546044 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -505,19 +505,19 @@ class PROTOBUF_EXPORT MessageLite { } template - static T* CreateMaybeMessage(Arena* arena) { - return Arena::CreateMaybeMessage(arena); + PROTOBUF_ALWAYS_INLINE static T* DefaultConstruct(Arena* arena) { + return static_cast(Arena::DefaultConstruct(arena)); } template - static T* CreateMaybeMessage(Arena* arena, const T& from) { - return Arena::CreateMaybeMessage(arena, from); + PROTOBUF_ALWAYS_INLINE static T* CopyConstruct(Arena* arena, const T& from) { + return static_cast(Arena::CopyConstruct(arena, &from)); } inline explicit MessageLite(Arena* arena) : _internal_metadata_(arena) {} // We use a secondary vtable for descriptor based methods. This way ClassData - // does not growth with the number of descriptor methods. This avoids extra + // does not grow with the number of descriptor methods. This avoids extra // costs in MessageLite. struct DescriptorMethods { std::string (*get_type_name)(const MessageLite&); @@ -527,11 +527,25 @@ class PROTOBUF_EXPORT MessageLite { // Note: The order of arguments in the functions is chosen so that it has // the same ABI as the member function that calls them. Eg the `this` // pointer becomes the first argument in the free function. - void (*merge_to_from)(Message& to, const Message& from_msg); + void (*merge_to_from)(MessageLite& to, const MessageLite& from_msg); void (*on_demand_register_arena_dtor)(MessageLite& msg, Arena& arena); // LITE objects (ie !descriptor_methods) collocate their name as a // char[] just beyond the ClassData. const DescriptorMethods* descriptor_methods; + + // Offset of the CachedSize member. + uint32_t cached_size_offset; + + constexpr ClassData(void (*merge_to_from)(MessageLite& to, + const MessageLite&), + void (*on_demand_register_arena_dtor)(MessageLite&, + Arena&), + const DescriptorMethods* descriptor_methods, + uint32_t cached_size_offset) + : merge_to_from(merge_to_from), + on_demand_register_arena_dtor(on_demand_register_arena_dtor), + descriptor_methods(descriptor_methods), + cached_size_offset(cached_size_offset) {} }; // GetClassData() returns a pointer to a ClassData struct which @@ -545,9 +559,9 @@ class PROTOBUF_EXPORT MessageLite { internal::InternalMetadata _internal_metadata_; - // The default implementation means there is no cached size and ByteSize - // should be called instead. - virtual internal::CachedSize* AccessCachedSize() const; + // Return the cached size object as described by + // ClassData::cached_size_offset. + internal::CachedSize& AccessCachedSize() const; public: enum ParseFlags { @@ -603,22 +617,22 @@ namespace internal { template bool MergeFromImpl(absl::string_view input, MessageLite* msg, MessageLite::ParseFlags parse_flags); -extern template bool MergeFromImpl(absl::string_view input, - MessageLite* msg, - MessageLite::ParseFlags parse_flags); -extern template bool MergeFromImpl(absl::string_view input, - MessageLite* msg, - MessageLite::ParseFlags parse_flags); +extern template PROTOBUF_EXPORT_TEMPLATE_DECLARE bool MergeFromImpl( + absl::string_view input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); +extern template PROTOBUF_EXPORT_TEMPLATE_DECLARE bool MergeFromImpl( + absl::string_view input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); template bool MergeFromImpl(io::ZeroCopyInputStream* input, MessageLite* msg, MessageLite::ParseFlags parse_flags); -extern template bool MergeFromImpl(io::ZeroCopyInputStream* input, - MessageLite* msg, - MessageLite::ParseFlags parse_flags); -extern template bool MergeFromImpl(io::ZeroCopyInputStream* input, - MessageLite* msg, - MessageLite::ParseFlags parse_flags); +extern template PROTOBUF_EXPORT_TEMPLATE_DECLARE bool MergeFromImpl( + io::ZeroCopyInputStream* input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); +extern template PROTOBUF_EXPORT_TEMPLATE_DECLARE bool MergeFromImpl( + io::ZeroCopyInputStream* input, MessageLite* msg, + MessageLite::ParseFlags parse_flags); struct BoundedZCIS { io::ZeroCopyInputStream* zcis; @@ -628,10 +642,10 @@ struct BoundedZCIS { template bool MergeFromImpl(BoundedZCIS input, MessageLite* msg, MessageLite::ParseFlags parse_flags); -extern template bool MergeFromImpl(BoundedZCIS input, MessageLite* msg, - MessageLite::ParseFlags parse_flags); -extern template bool MergeFromImpl(BoundedZCIS input, MessageLite* msg, - MessageLite::ParseFlags parse_flags); +extern template PROTOBUF_EXPORT_TEMPLATE_DECLARE bool MergeFromImpl( + BoundedZCIS input, MessageLite* msg, MessageLite::ParseFlags parse_flags); +extern template PROTOBUF_EXPORT_TEMPLATE_DECLARE bool MergeFromImpl( + BoundedZCIS input, MessageLite* msg, MessageLite::ParseFlags parse_flags); template struct SourceWrapper; diff --git a/src/google/protobuf/message_unittest.inc b/src/google/protobuf/message_unittest.inc index 4e07c69367..9ae5faec06 100644 --- a/src/google/protobuf/message_unittest.inc +++ b/src/google/protobuf/message_unittest.inc @@ -101,6 +101,24 @@ TEST(MESSAGE_TEST_NAME, SerializeHelpers) { } +TEST(MESSAGE_TEST_NAME, RoundTrip) { + UNITTEST::TestAllTypes message; + TestUtil::SetAllFields(&message); + TestUtil::ExpectAllFieldsSet(message); + + UNITTEST::TestAllTypes copied, merged, parsed; + copied = message; + TestUtil::ExpectAllFieldsSet(copied); + + merged.MergeFrom(message); + TestUtil::ExpectAllFieldsSet(merged); + + std::string data; + ASSERT_TRUE(message.SerializeToString(&data)); + ASSERT_TRUE(parsed.ParseFromString(data)); + TestUtil::ExpectAllFieldsSet(parsed); +} + TEST(MESSAGE_TEST_NAME, SerializeToBrokenOstream) { std::ofstream out; UNITTEST::TestAllTypes message; @@ -1937,9 +1955,10 @@ TEST(MESSAGE_TEST_NAME, TestRegressionInlinedStringAuxIdxMismatchOnFastParser) { if (table != nullptr && table->fast_entry(1)->target() == internal::TcParser::FastSiS1) { // optional string str1 = 1; + // The aux_idx points to the inlined_string_idx and not the actual aux_idx. EXPECT_EQ(table->fast_entry(1)->bits.aux_idx(), 1); // optional InlinedStringIdxRegressionProto sub = 2; - EXPECT_EQ(table->fast_entry(2)->bits.aux_idx(), 2); + EXPECT_EQ(table->fast_entry(2)->bits.aux_idx(), 1); // optional string str2 = 3; // The aux_idx points to the inlined_string_idx and not the actual aux_idx. EXPECT_EQ(table->fast_entry(3)->bits.aux_idx(), 2); diff --git a/src/google/protobuf/port.h b/src/google/protobuf/port.h index 51e63e30e2..a5f3b98b12 100644 --- a/src/google/protobuf/port.h +++ b/src/google/protobuf/port.h @@ -22,6 +22,7 @@ #include +#include "absl/base/config.h" #include "absl/meta/type_traits.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" @@ -37,6 +38,16 @@ class MessageLite; namespace internal { +template +void StrongPointer(T* var) { +#if defined(__GNUC__) + asm("" : : "r"(var)); +#else + auto volatile unused = var; + (void)&unused; // Use address to avoid an extra load of "unused". +#endif +} + // See comments on `AllocateAtLeast` for information on size returning new. struct SizedPtr { @@ -201,6 +212,22 @@ inline constexpr bool DebugHardenStringValues() { #endif } +#if defined(NDEBUG) && ABSL_HAVE_BUILTIN(__builtin_unreachable) +[[noreturn]] ABSL_ATTRIBUTE_COLD PROTOBUF_ALWAYS_INLINE inline void +Unreachable() { + __builtin_unreachable(); +} +#elif ABSL_HAVE_BUILTIN(__builtin_FILE) && ABSL_HAVE_BUILTIN(__builtin_LINE) +[[noreturn]] ABSL_ATTRIBUTE_COLD inline void Unreachable( + const char* file = __builtin_FILE(), int line = __builtin_LINE()) { + protobuf_assumption_failed("Unreachable", file, line); +} +#else +[[noreturn]] ABSL_ATTRIBUTE_COLD inline void Unreachable() { + protobuf_assumption_failed("Unreachable", "", 0); +} +#endif + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index 86ed3ea7d7..edf0fccdf0 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc @@ -67,21 +67,6 @@ // - MSVC: https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes-history // https://docs.microsoft.com/en-us/visualstudio/releasenotes/vs2017-relnotes-history -// Portable fallback for Clang's __has_warning macro: -#ifndef __has_warning -#define __has_warning(x) 0 -#define PROTOBUF_has_warning_DEFINED_ -#endif - -#ifdef ADDRESS_SANITIZER -#include -#define PROTOBUF_POISON_MEMORY_REGION(p, n) ASAN_POISON_MEMORY_REGION(p, n) -#define PROTOBUF_UNPOISON_MEMORY_REGION(p, n) ASAN_UNPOISON_MEMORY_REGION(p, n) -#else // ADDRESS_SANITIZER -#define PROTOBUF_POISON_MEMORY_REGION(p, n) -#define PROTOBUF_UNPOISON_MEMORY_REGION(p, n) -#endif // ADDRESS_SANITIZER - // Portable PROTOBUF_BUILTIN_BSWAPxx definitions // Code must check for availability, e.g.: `defined(PROTOBUF_BUILTIN_BSWAP32)` #ifdef PROTOBUF_BUILTIN_BSWAP16 @@ -103,11 +88,6 @@ #define PROTOBUF_BUILTIN_BSWAP64(x) __builtin_bswap64(x) #endif -// Portable check for __builtin_mul_overflow. -#if ABSL_HAVE_BUILTIN(__builtin_mul_overflow) -#define PROTOBUF_HAS_BUILTIN_MUL_OVERFLOW 1 -#endif - // Portable check for gcc-style atomic built-ins #if ABSL_HAVE_BUILTIN(__atomic_load_n) #define PROTOBUF_BUILTIN_ATOMIC 1 @@ -179,10 +159,6 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), #ifdef PROTOBUF_FUTURE_BREAKING_CHANGES -// Used to remove the manipulation of cleared elements in RepeatedPtrField. -// Owner: mkruskal@ -#define PROTOBUF_FUTURE_REMOVE_CLEARED_API 1 - // Used for descriptor proto extension declarations. // Owner: shaod@, gberg@ #define PROTOBUF_FUTURE_DESCRIPTOR_EXTENSION_DECL 1 @@ -191,30 +167,18 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), // Owner: ezb@ #define PROTOBUF_FUTURE_REMOVE_CONST_REPEATEDFIELD_GETARENA_API 1 -// Used to make ExtensionRange into a fully-fledged descriptor class. -// Owner: mkruskal@ -#define PROTOBUF_FUTURE_EXTENSION_RANGE_CLASS 1 - // Used to lock down wrong ctype usages in proto file. // Owner: jieluo@ #define PROTOBUF_FUTURE_REMOVE_WRONG_CTYPE 1 #endif +// Defines the Protobuf C++ Version for checking version compatibility at +// compilation time. #ifdef PROTOBUF_VERSION #error PROTOBUF_VERSION was previously defined #endif -#define PROTOBUF_VERSION 4024000 - -#ifdef PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC -#error PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC was previously defined -#endif -#define PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC 4024000 - -#ifdef PROTOBUF_MIN_PROTOC_VERSION -#error PROTOBUF_MIN_PROTOC_VERSION was previously defined -#endif -#define PROTOBUF_MIN_PROTOC_VERSION 4024000 +#define PROTOBUF_VERSION 4026000 #ifdef PROTOBUF_VERSION_SUFFIX #error PROTOBUF_VERSION_SUFFIX was previously defined @@ -328,10 +292,6 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), #define PROTOBUF_IGNORE_DEPRECATION_STOP #endif -// The minimum library version which works with the current version of the -// headers. -#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 4024000 - #ifdef PROTOBUF_RTTI #error PROTOBUF_RTTI was previously defined #endif @@ -533,11 +493,6 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), #define PROTOBUF_ALIGNAS(byte_alignment) alignas(byte_alignment) #endif -#ifdef PROTOBUF_FINAL -#error PROTOBUF_FINAL was previously defined -#endif -#define PROTOBUF_FINAL final - #ifdef PROTOBUF_THREAD_LOCAL #error PROTOBUF_THREAD_LOCAL was previously defined #endif @@ -600,21 +555,6 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), #define PROTOBUF_ATTRIBUTE_NO_DESTROY #endif -// Force clang to always emit complete debug info for a type. -// Clang uses constructor homing to determine when to emit debug info for a -// type. If the constructor of a type is never used, which can happen in some -// cases where member variables are constructed in place for optimization -// purposes (see b/208803175 for an example), the type will have incomplete -// debug info unless this attribute is used. -#ifdef PROTOBUF_ATTRIBUTE_STANDALONE_DEBUG -#error PROTOBUF_ATTRIBUTE_STANDALONE_DEBUG was previously defined -#endif -#if ABSL_HAVE_CPP_ATTRIBUTE(clang::standalone_debug) -#define PROTOBUF_ATTRIBUTE_STANDALONE_DEBUG [[clang::standalone_debug]] -#else -#define PROTOBUF_ATTRIBUTE_STANDALONE_DEBUG -#endif - // Protobuf extensions and reflection require registration of the protos linked // in the binary. Not until everything is registered does the runtime have a // complete view on all protos. When code is using reflection or extensions @@ -692,8 +632,22 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), # define PROTOBUF_TSAN 1 # endif # endif +# ifdef __SANITIZE_MEMORY__ +# if __SANITIZE_MEMORY__ +# define PROTOBUF_ASAN 1 +# endif +# endif #endif +#ifdef PROTOBUF_ASAN +#include +#define PROTOBUF_POISON_MEMORY_REGION(p, n) ASAN_POISON_MEMORY_REGION(p, n) +#define PROTOBUF_UNPOISON_MEMORY_REGION(p, n) ASAN_UNPOISON_MEMORY_REGION(p, n) +#else // PROTOBUF_ASAN +#define PROTOBUF_POISON_MEMORY_REGION(p, n) +#define PROTOBUF_UNPOISON_MEMORY_REGION(p, n) +#endif // PROTOBUF_ASAN + #ifdef PROTOBUF_TSAN_READ #error PROTOBUF_TSAN_READ was previously defined #endif @@ -789,8 +743,30 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), #define PROTOBUF_BUILTIN_CONSTANT_P(x) false #endif +// Determines the platforms where descriptor weak messages can be used. +#ifdef PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED +#error PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED was previously defined +#endif +#if defined(__GNUC__) && defined(__clang__) && !defined(__APPLE__) && \ + !defined(_MSC_VER) +#define PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED +#endif + + +// TODO: Enable the feature by default and remove this flag. +#ifdef PROTOBUF_PREFETCH_PARSE_TABLE +#error PROTOBUF_PREFETCH_PARSE_TABLE was previously defined +#endif + // ThreadSafeArenaz is turned off completely in opensource builds. +// noreturn is defined as a macro in C's stdnoreturn.h +#ifdef noreturn +#define PROTOBUF_DID_UNDEF_noreturn +#pragma push_macro("noreturn") +#undef noreturn +#endif + // autoheader defines this in some circumstances #ifdef PACKAGE #define PROTOBUF_DID_UNDEF_PACKAGE @@ -1019,8 +995,9 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), namespace google { namespace protobuf { namespace internal { -PROTOBUF_EXPORT void protobuf_assumption_failed(const char *pred, - const char *file, int line); +[[noreturn]] PROTOBUF_EXPORT void protobuf_assumption_failed(const char *pred, + const char *file, + int line); } // namespace internal } // namespace protobuf } // namespace google @@ -1054,10 +1031,3 @@ PROTOBUF_EXPORT void protobuf_assumption_failed(const char *pred, #endif // !NDEBUG #endif // has_builtin(__builtin_assume) -// We don't want code outside port_def doing complex testing, so -// remove our portable condition test macros to nudge folks away from -// using it themselves. -#ifdef PROTOBUF_has_warning_DEFINED_ -# undef __has_warning -# undef PROTOBUF_has_warning_DEFINED_ -#endif diff --git a/src/google/protobuf/port_test.cc b/src/google/protobuf/port_test.cc index d1174c3a1b..a8c6402819 100644 --- a/src/google/protobuf/port_test.cc +++ b/src/google/protobuf/port_test.cc @@ -5,10 +5,13 @@ // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd // +#include "google/protobuf/port.h" + #include #include #include +#include "absl/base/config.h" // Must be included last #include "google/protobuf/port_def.inc" @@ -28,6 +31,21 @@ TEST(PortTest, ProtobufAssume) { #endif } +TEST(PortTest, UnreachableTrapsOnDebugMode) { +#ifdef GTEST_HAS_DEATH_TEST +#if defined(NDEBUG) + // In NDEBUG we crash with a UD instruction, so we don't get the "Assumption + // failed" error. + GTEST_SKIP() << "Can't test __builtin_unreachable()"; +#elif ABSL_HAVE_BUILTIN(__builtin_FILE) + EXPECT_DEATH(Unreachable(), + "port_test\\.cc:.*Assumption failed: 'Unreachable'"); +#else + EXPECT_DEATH(Unreachable(), "Assumption failed: 'Unreachable'"); +#endif +#endif +} + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc index 49aeb64865..a107fb325f 100644 --- a/src/google/protobuf/port_undef.inc +++ b/src/google/protobuf/port_undef.inc @@ -19,7 +19,6 @@ #undef PROTOBUF_BUILTIN_BSWAP16 #undef PROTOBUF_BUILTIN_BSWAP32 #undef PROTOBUF_BUILTIN_BSWAP64 -#undef PROTOBUF_HAS_BUILTIN_MUL_OVERFLOW #undef PROTOBUF_BUILTIN_ATOMIC #undef PROTOBUF_GNUC_MIN #undef PROTOBUF_CLANG_MIN @@ -40,8 +39,6 @@ #undef PROTOBUF_MINIMUM_EDITION #undef PROTOBUF_MAXIMUM_EDITION #undef PROTOBUF_FIELD_OFFSET -#undef PROTOBUF_MIN_HEADER_VERSION_FOR_PROTOC -#undef PROTOBUF_MIN_PROTOC_VERSION #undef PROTOBUF_PREDICT_TRUE #undef PROTOBUF_PREDICT_FALSE #undef PROTOBUF_EXPORT @@ -60,7 +57,6 @@ #undef PROTOBUF_EXPORT_TEMPLATE_DECLARE #undef PROTOBUF_EXPORT_TEMPLATE_DEFINE #undef PROTOBUF_ALIGNAS -#undef PROTOBUF_FINAL #undef PROTOBUF_THREAD_LOCAL #undef PROTOBUF_CONSTINIT #undef PROTOBUF_CONSTEXPR @@ -68,7 +64,6 @@ #undef PROTOBUF_ATTRIBUTE_WEAK #undef PROTOBUF_HAVE_ATTRIBUTE_WEAK #undef PROTOBUF_ATTRIBUTE_NO_DESTROY -#undef PROTOBUF_ATTRIBUTE_STANDALONE_DEBUG #undef PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 #undef PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 #undef PROTOBUF_PRAGMA_INIT_SEG @@ -80,6 +75,8 @@ #undef PROTOBUF_TSAN_WRITE #undef PROTOBUF_USE_TABLE_PARSER_ON_REFLECTION #undef PROTOBUF_BUILTIN_CONSTANT_P +#undef PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED +#undef PROTOBUF_PREFETCH_PARSE_TABLE #undef PROTOBUF_TC_PARAM_DECL #undef PROTOBUF_DEBUG #undef PROTO2_IS_OSS @@ -87,12 +84,16 @@ #ifdef PROTOBUF_FUTURE_BREAKING_CHANGES #undef PROTOBUF_FUTURE_BREAKING_CHANGES -#undef PROTOBUF_FUTURE_REMOVE_CLEARED_API #undef PROTOBUF_FUTURE_DESCRIPTOR_EXTENSION_DECL #endif // Restore macros that may have been #undef'd in port_def.inc. +#ifdef PROTOBUF_DID_UNDEF_noreturn +#pragma pop_macro("noreturn") +#undef PROTOBUF_DID_UNDEF_noreturn +#endif + #ifdef PROTOBUF_DID_UNDEF_PACKAGE #pragma pop_macro("PACKAGE") #undef PROTOBUF_DID_UNDEF_PACKAGE diff --git a/src/google/protobuf/proto3_arena_unittest.cc b/src/google/protobuf/proto3_arena_unittest.cc index 7a46ab6f20..87088158a5 100644 --- a/src/google/protobuf/proto3_arena_unittest.cc +++ b/src/google/protobuf/proto3_arena_unittest.cc @@ -12,7 +12,6 @@ #include #include "absl/strings/match.h" #include "google/protobuf/arena.h" -#include "google/protobuf/descriptor_legacy.h" #include "google/protobuf/test_util.h" #include "google/protobuf/text_format.h" #include "google/protobuf/unittest.pb.h" @@ -152,7 +151,7 @@ TEST(Proto3ArenaTest, GetArena) { // Tests message created by Arena::Create. auto* arena_message3 = Arena::Create(&arena); - EXPECT_EQ(nullptr, arena_message3->GetArena()); + EXPECT_EQ(&arena, arena_message3->GetArena()); } TEST(Proto3ArenaTest, GetArenaWithUnknown) { @@ -262,15 +261,13 @@ TEST(Proto3OptionalTest, OptionalFieldDescriptor) { for (int i = 0; i < d->field_count(); i++) { const FieldDescriptor* f = d->field(i); if (absl::StartsWith(f->name(), "singular")) { - EXPECT_FALSE(FieldDescriptorLegacy(f).has_optional_keyword()) - << f->full_name(); EXPECT_FALSE(f->has_presence()) << f->full_name(); EXPECT_FALSE(f->containing_oneof()) << f->full_name(); + EXPECT_FALSE(f->real_containing_oneof()) << f->full_name(); } else { - EXPECT_TRUE(FieldDescriptorLegacy(f).has_optional_keyword()) - << f->full_name(); EXPECT_TRUE(f->has_presence()) << f->full_name(); EXPECT_TRUE(f->containing_oneof()) << f->full_name(); + EXPECT_FALSE(f->real_containing_oneof()) << f->full_name(); } } } @@ -283,8 +280,6 @@ TEST(Proto3OptionalTest, Extensions) { "protobuf_unittest.Proto3OptionalExtensions.ext_with_optional"); ABSL_CHECK(no_optional); ABSL_CHECK(with_optional); - EXPECT_FALSE(FieldDescriptorLegacy(no_optional).has_optional_keyword()); - EXPECT_TRUE(FieldDescriptorLegacy(with_optional).has_optional_keyword()); const Descriptor* d = protobuf_unittest::Proto3OptionalExtensions::descriptor(); EXPECT_TRUE(d->options().HasExtension( @@ -332,7 +327,8 @@ TEST(Proto3OptionalTest, OptionalFieldReflection) { const google::protobuf::OneofDescriptor* o = d->FindOneofByName("_optional_int32"); ABSL_CHECK(f); ABSL_CHECK(o); - EXPECT_TRUE(OneofDescriptorLegacy(o).is_synthetic()); + EXPECT_EQ(f->containing_oneof(), o); + EXPECT_EQ(f->real_containing_oneof(), nullptr); EXPECT_FALSE(r->HasField(msg, f)); EXPECT_FALSE(r->HasOneof(msg, o)); diff --git a/src/google/protobuf/reflection_ops.cc b/src/google/protobuf/reflection_ops.cc index 03b0d38b69..233d25847c 100644 --- a/src/google/protobuf/reflection_ops.cc +++ b/src/google/protobuf/reflection_ops.cc @@ -262,7 +262,13 @@ bool ReflectionOps::IsInitialized(const Message& message) { std::vector fields; // Should be safe to skip stripped fields because required fields are not // stripped. - reflection->ListFields(message, &fields); + if (descriptor->options().map_entry()) { + // MapEntry objects always check the value regardless of has bit. + // We don't need to bother with the key. + fields = {descriptor->map_value()}; + } else { + reflection->ListFields(message, &fields); + } for (const FieldDescriptor* field : fields) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { @@ -327,10 +333,10 @@ void ReflectionOps::DiscardUnknownFields(Message* message) { continue; } // Discard the unknown fields in maps that contain message values. - if (field->is_map() && IsMapValueMessageTyped(field)) { - const MapFieldBase* map_field = - reflection->MutableMapData(message, field); - if (map_field->IsMapValid()) { + const MapFieldBase* map_field = + field->is_map() ? reflection->MutableMapData(message, field) : nullptr; + if (map_field != nullptr && map_field->IsMapValid()) { + if (IsMapValueMessageTyped(field)) { MapIterator iter(message, field); MapIterator end(message, field); for (map_field->MapBegin(&iter), map_field->MapEnd(&end); iter != end; diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index 0647790b78..5351846558 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -162,7 +162,8 @@ class RepeatedField final RepeatedField& operator=(const RepeatedField& other) ABSL_ATTRIBUTE_LIFETIME_BOUND; - RepeatedField(RepeatedField&& other) noexcept; + RepeatedField(RepeatedField&& rhs) noexcept + : RepeatedField(nullptr, std::move(rhs)) {} RepeatedField& operator=(RepeatedField&& other) noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND; @@ -329,6 +330,7 @@ class RepeatedField final static PROTOBUF_CONSTEXPR const size_t kRepHeaderSize = sizeof(Rep); RepeatedField(Arena* arena, const RepeatedField& rhs); + RepeatedField(Arena* arena, RepeatedField&& rhs); // Swaps entire contents with "other". Should be called only if the caller can @@ -515,18 +517,17 @@ inline RepeatedField& RepeatedField::operator=( } template -inline RepeatedField::RepeatedField(RepeatedField&& other) noexcept - : RepeatedField() { +inline RepeatedField::RepeatedField(Arena* arena, RepeatedField&& rhs) + : RepeatedField(arena) { #ifdef PROTOBUF_FORCE_COPY_IN_MOVE - CopyFrom(other); + CopyFrom(rhs); #else // PROTOBUF_FORCE_COPY_IN_MOVE - // We don't just call Swap(&other) here because it would perform 3 copies if - // other is on an arena. This field can't be on an arena because arena - // construction always uses the Arena* accepting constructor. - if (other.GetArena()) { - CopyFrom(other); + // We don't just call Swap(&rhs) here because it would perform 3 copies if rhs + // is on a different arena. + if (arena != rhs.GetArena()) { + CopyFrom(rhs); } else { - InternalSwap(&other); + InternalSwap(&rhs); } #endif // !PROTOBUF_FORCE_COPY_IN_MOVE } @@ -1034,14 +1035,18 @@ namespace internal { // the compiler isn't allowed to inline them. template class RepeatedIterator { + private: + using traits = + std::iterator_traits::type*>; + public: - using iterator_category = std::random_access_iterator_tag; - // Note: remove_const is necessary for std::partial_sum, which uses value_type - // to determine the summation variable type. - using value_type = typename std::remove_const::type; - using difference_type = std::ptrdiff_t; + // Note: value_type is never cv-qualified. + using value_type = typename traits::value_type; + using difference_type = typename traits::difference_type; using pointer = Element*; using reference = Element&; + using iterator_category = typename traits::iterator_category; + using iterator_concept = typename IteratorConceptSupport::tag; constexpr RepeatedIterator() noexcept : it_(nullptr) {} @@ -1141,10 +1146,10 @@ class RepeatedIterator { // Allow construction from RepeatedField. friend class RepeatedField; - explicit RepeatedIterator(Element* it) noexcept : it_(it) {} + explicit RepeatedIterator(pointer it) noexcept : it_(it) {} // The internal iterator. - Element* it_; + pointer it_; }; // A back inserter for RepeatedField objects. diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index 529d872284..d99aae6f52 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -33,6 +33,7 @@ #include #include "absl/log/absl_check.h" #include "absl/numeric/bits.h" +#include "absl/random/random.h" #include "absl/strings/cord.h" #include "absl/strings/str_cat.h" #include "absl/types/span.h" @@ -59,6 +60,74 @@ using ::testing::ElementsAre; using ::testing::Ge; using ::testing::Le; +TEST(RepeatedFieldIterator, Traits) { + using It = RepeatedField::iterator; + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); +#if __cplusplus >= 202002L + EXPECT_TRUE(( + std::is_same::value)); +#else + EXPECT_TRUE((std::is_same::value)); +#endif +} + +TEST(ConstRepeatedFieldIterator, Traits) { + using It = RepeatedField::const_iterator; + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); +#if __cplusplus >= 202002L + EXPECT_TRUE(( + std::is_same::value)); +#else + EXPECT_TRUE((std::is_same::value)); +#endif +} + +TEST(RepeatedPtrOverPtrsIterator, Traits) { + using It = RepeatedPtrField::pointer_iterator; + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); +#if __cplusplus >= 202002L + EXPECT_TRUE(( + std::is_same::value)); +#else + EXPECT_TRUE((std::is_same::value)); +#endif +} + +TEST(ConstRepeatedPtrOverPtrsIterator, Traits) { + using It = RepeatedPtrField::const_pointer_iterator; + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); + EXPECT_TRUE((std::is_same::value)); +#if __cplusplus >= 202002L + EXPECT_TRUE(( + std::is_same::value)); +#else + EXPECT_TRUE((std::is_same::value)); +#endif +} + TEST(RepeatedField, ConstInit) { PROTOBUF_CONSTINIT static RepeatedField field{}; // NOLINT EXPECT_TRUE(field.empty()); @@ -450,7 +519,7 @@ TEST(RepeatedField, ReserveLarge) { } TEST(RepeatedField, ReserveHuge) { -#if defined(ABSL_HAVE_ADDRESS_SANITIZER) || defined(ABSL_HAVE_MEMORY_SANITIZER) +#if defined(PROTOBUF_ASAN) || defined(PROTOBUF_MSAN) GTEST_SKIP() << "Disabled because sanitizer is active"; #endif // Largest value that does not clamp to the large limit: @@ -704,9 +773,9 @@ TEST(RepeatedField, CopyConstructIntegers) { EXPECT_EQ(2, fields1.Get(1)); RepeatedType fields2(token, nullptr, original); - ASSERT_EQ(2, fields1.size()); - EXPECT_EQ(1, fields1.Get(0)); - EXPECT_EQ(2, fields1.Get(1)); + ASSERT_EQ(2, fields2.size()); + EXPECT_EQ(1, fields2.Get(0)); + EXPECT_EQ(2, fields2.Get(1)); } TEST(RepeatedField, CopyConstructCords) { @@ -1172,17 +1241,17 @@ TEST(RepeatedField, HardenAgainstBadTruncate) { } } -#if defined(GTEST_HAS_DEATH_TEST) && (defined(ABSL_HAVE_ADDRESS_SANITIZER) || \ - defined(ABSL_HAVE_MEMORY_SANITIZER)) +#if defined(GTEST_HAS_DEATH_TEST) && \ + (defined(PROTOBUF_ASAN) || defined(PROTOBUF_MSAN)) // This function verifies that the code dies under ASAN or MSAN trying to both // read and write the reserved element directly beyond the last element. void VerifyDeathOnWriteAndReadAccessBeyondEnd(RepeatedField& field) { auto* end = field.Mutable(field.size() - 1) + 1; -#if defined(ABSL_HAVE_ADDRESS_SANITIZER) +#if defined(PROTOBUF_ASAN) EXPECT_DEATH(*end = 1, "container-overflow"); EXPECT_DEATH(EXPECT_NE(*end, 1), "container-overflow"); -#elif defined(ABSL_HAVE_MEMORY_SANITIZER) +#elif defined(PROTOBUF_MSAN) EXPECT_DEATH(EXPECT_NE(*end, 1), "use-of-uninitialized-value"); #endif @@ -1606,19 +1675,6 @@ TEST(RepeatedPtrField, ClearedElements) { field.Clear(); EXPECT_EQ(field.ClearedCount(), 2); -#ifndef PROTOBUF_FUTURE_REMOVE_CLEARED_API - EXPECT_EQ(field.ReleaseCleared(), original); // Take ownership again. - EXPECT_EQ(field.ClearedCount(), 1); - EXPECT_NE(field.Add(), original); - EXPECT_EQ(field.ClearedCount(), 0); - EXPECT_NE(field.Add(), original); - EXPECT_EQ(field.ClearedCount(), 0); - - field.AddCleared(original); // Give ownership back, but as a cleared object. - EXPECT_EQ(field.ClearedCount(), 1); - EXPECT_EQ(field.Add(), original); - EXPECT_EQ(field.ClearedCount(), 0); -#endif // !PROTOBUF_FUTURE_REMOVE_CLEARED_API PROTOBUF_IGNORE_DEPRECATION_STOP } diff --git a/src/google/protobuf/repeated_ptr_field.cc b/src/google/protobuf/repeated_ptr_field.cc index 19b4ca59c4..49c29fe433 100644 --- a/src/google/protobuf/repeated_ptr_field.cc +++ b/src/google/protobuf/repeated_ptr_field.cc @@ -19,7 +19,7 @@ #include "absl/base/prefetch.h" #include "absl/log/absl_check.h" #include "google/protobuf/arena.h" -#include "google/protobuf/implicit_weak_message.h" +#include "google/protobuf/message_lite.h" #include "google/protobuf/port.h" #include "google/protobuf/repeated_field.h" @@ -34,10 +34,11 @@ namespace internal { void** RepeatedPtrFieldBase::InternalExtend(int extend_amount) { ABSL_DCHECK(extend_amount > 0); constexpr size_t ptr_size = sizeof(rep()->elements[0]); - int new_capacity = total_size_ + extend_amount; + int capacity = Capacity(); + int new_capacity = capacity + extend_amount; Arena* arena = GetArena(); new_capacity = internal::CalculateReserveSize( - total_size_, new_capacity); + capacity, new_capacity); ABSL_CHECK_LE( static_cast(new_capacity), static_cast( @@ -45,7 +46,6 @@ void** RepeatedPtrFieldBase::InternalExtend(int extend_amount) { << "Requested size is too large to fit into size_t."; size_t bytes = kRepHeaderSize + ptr_size * new_capacity; Rep* new_rep; - void* old_tagged_ptr = tagged_rep_or_elem_; if (arena == nullptr) { internal::SizedPtr res = internal::AllocateAtLeast(bytes); new_capacity = static_cast((res.n - kRepHeaderSize) / ptr_size); @@ -55,18 +55,17 @@ void** RepeatedPtrFieldBase::InternalExtend(int extend_amount) { } if (using_sso()) { - new_rep->allocated_size = old_tagged_ptr != nullptr ? 1 : 0; - new_rep->elements[0] = old_tagged_ptr; + new_rep->allocated_size = tagged_rep_or_elem_ != nullptr ? 1 : 0; + new_rep->elements[0] = tagged_rep_or_elem_; } else { - Rep* old_rep = - reinterpret_cast(reinterpret_cast(old_tagged_ptr) - 1); + Rep* old_rep = rep(); if (old_rep->allocated_size > 0) { memcpy(new_rep->elements, old_rep->elements, old_rep->allocated_size * ptr_size); } new_rep->allocated_size = old_rep->allocated_size; - size_t old_size = total_size_ * ptr_size + kRepHeaderSize; + size_t old_size = capacity * ptr_size + kRepHeaderSize; if (arena == nullptr) { internal::SizedDelete(old_rep, old_size); } else { @@ -76,77 +75,59 @@ void** RepeatedPtrFieldBase::InternalExtend(int extend_amount) { tagged_rep_or_elem_ = reinterpret_cast(reinterpret_cast(new_rep) + 1); - total_size_ = new_capacity; + capacity_proxy_ = new_capacity - kSSOCapacity; return &new_rep->elements[current_size_]; } void RepeatedPtrFieldBase::Reserve(int capacity) { - if (capacity > total_size_) { - InternalExtend(capacity - total_size_); + int delta = capacity - Capacity(); + if (delta > 0) { + InternalExtend(delta); } } void RepeatedPtrFieldBase::DestroyProtos() { - ABSL_DCHECK(tagged_rep_or_elem_); - ABSL_DCHECK(arena_ == nullptr); - if (using_sso()) { - delete static_cast(tagged_rep_or_elem_); - } else { - Rep* r = rep(); - int n = r->allocated_size; - void* const* elements = r->elements; - for (int i = 0; i < n; i++) { - delete static_cast(elements[i]); - } - const size_t size = total_size_ * sizeof(elements[0]) + kRepHeaderSize; - internal::SizedDelete(r, size); - } + PROTOBUF_ALWAYS_INLINE_CALL Destroy>(); // TODO: Eliminate this store when invoked from the destructor, // since it is dead. tagged_rep_or_elem_ = nullptr; } -void* RepeatedPtrFieldBase::AddOutOfLineHelper(void* obj) { +template +auto* RepeatedPtrFieldBase::AddInternal(F factory) { + Arena* const arena = GetArena(); + using Result = decltype(factory(arena)); if (tagged_rep_or_elem_ == nullptr) { - ABSL_DCHECK_EQ(current_size_, 0); - ABSL_DCHECK(using_sso()); - ABSL_DCHECK_EQ(allocated_size(), 0); ExchangeCurrentSize(1); - return tagged_rep_or_elem_ = obj; - } - if (using_sso() || rep()->allocated_size == total_size_) { - InternalExtend(1); // Equivalent to "Reserve(total_size_ + 1)" - } - Rep* r = rep(); - ++r->allocated_size; - return r->elements[ExchangeCurrentSize(current_size_ + 1)] = obj; -} - -void* RepeatedPtrFieldBase::AddOutOfLineHelper(ElementFactory factory) { - if (tagged_rep_or_elem_ == nullptr) { - ExchangeCurrentSize(1); - tagged_rep_or_elem_ = factory(GetArena()); - return tagged_rep_or_elem_; + tagged_rep_or_elem_ = factory(arena); + return static_cast(tagged_rep_or_elem_); } if (using_sso()) { - if (ExchangeCurrentSize(1) == 0) return tagged_rep_or_elem_; + if (ExchangeCurrentSize(1) == 0) { + return static_cast(tagged_rep_or_elem_); + } } else { absl::PrefetchToLocalCache(rep()); } - if (PROTOBUF_PREDICT_FALSE(current_size_ == total_size_)) { + if (PROTOBUF_PREDICT_FALSE(SizeAtCapacity())) { InternalExtend(1); } else { Rep* r = rep(); if (current_size_ != r->allocated_size) { - return r->elements[ExchangeCurrentSize(current_size_ + 1)]; + return static_cast( + r->elements[ExchangeCurrentSize(current_size_ + 1)]); } } Rep* r = rep(); ++r->allocated_size; void*& result = r->elements[ExchangeCurrentSize(current_size_ + 1)]; - result = factory(GetArena()); - return result; + result = factory(arena); + return static_cast(result); +} + +void* RepeatedPtrFieldBase::AddOutOfLineHelper(ElementFactory factory) { + return AddInternal(factory); } void RepeatedPtrFieldBase::CloseGap(int start, int num) { @@ -164,15 +145,8 @@ void RepeatedPtrFieldBase::CloseGap(int start, int num) { ExchangeCurrentSize(current_size_ - num); } -MessageLite* RepeatedPtrFieldBase::AddWeak(const MessageLite* prototype) { - if (current_size_ < allocated_size()) { - return reinterpret_cast( - element_at(ExchangeCurrentSize(current_size_ + 1))); - } - MessageLite* result = prototype - ? prototype->New(arena_) - : Arena::CreateMessage(arena_); - return static_cast(AddOutOfLineHelper(result)); +MessageLite* RepeatedPtrFieldBase::AddMessage(const MessageLite* prototype) { + return AddInternal([prototype](Arena* a) { return prototype->New(a); }); } void InternalOutOfLineDeleteMessageLite(MessageLite* message) { @@ -232,8 +206,8 @@ void RepeatedPtrFieldBase::MergeFromConcreteMessage( const RepeatedPtrFieldBase& from, CopyFn copy_fn) { ABSL_DCHECK_NE(&from, this); int new_size = current_size_ + from.current_size_; - auto dst = reinterpret_cast(InternalReserve(new_size)); - auto src = reinterpret_cast(from.elements()); + void** dst = InternalReserve(new_size); + const void* const* src = from.elements(); auto end = src + from.current_size_; if (PROTOBUF_PREDICT_FALSE(ClearedCount() > 0)) { int recycled = MergeIntoClearedMessages(from); @@ -242,7 +216,7 @@ void RepeatedPtrFieldBase::MergeFromConcreteMessage( } Arena* arena = GetArena(); for (; src < end; ++src, ++dst) { - *dst = copy_fn(arena, **src); + *dst = copy_fn(arena, *src); } ExchangeCurrentSize(new_size); if (new_size > allocated_size()) { @@ -283,6 +257,10 @@ void RepeatedPtrFieldBase::MergeFrom( } } +void* NewStringElement(Arena* arena) { + return Arena::Create(arena); +} + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/repeated_ptr_field.h b/src/google/protobuf/repeated_ptr_field.h index 5894e777e2..644bdb4757 100644 --- a/src/google/protobuf/repeated_ptr_field.h +++ b/src/google/protobuf/repeated_ptr_field.h @@ -33,6 +33,7 @@ #include "absl/base/attributes.h" #include "absl/log/absl_check.h" +#include "absl/meta/type_traits.h" #include "google/protobuf/arena.h" #include "google/protobuf/internal_visibility.h" #include "google/protobuf/message_lite.h" @@ -72,11 +73,6 @@ class RepeatedPtrOverPtrsIterator; namespace internal { -template -inline void* NewT(Arena* a) { - return GenericTypeHandler::New(a); -} - // Swaps two non-overlapping blocks of memory of size `N` template inline void memswap(char* PROTOBUF_RESTRICT a, char* PROTOBUF_RESTRICT b) { @@ -85,48 +81,6 @@ inline void memswap(char* PROTOBUF_RESTRICT a, char* PROTOBUF_RESTRICT b) { std::swap_ranges(a, a + N, b); } -// type-traits helper for RepeatedPtrFieldBase: we only want to invoke -// arena-related "copy if on different arena" behavior if the necessary methods -// exist on the contained type. In particular, we rely on MergeFrom() existing -// as a general proxy for the fact that a copy will work, and we also provide a -// specific override for std::string*. -template -struct TypeImplementsMergeBehaviorProbeForMergeFrom { - typedef char HasMerge; - typedef long HasNoMerge; - - // We accept either of: - // - void MergeFrom(const T& other) - // - bool MergeFrom(const T& other) - // - // We mangle these names a bit to avoid compatibility issues in 'unclean' - // include environments that may have, e.g., "#define test ..." (yes, this - // exists). - template - struct CheckType; - template - static HasMerge Check(CheckType*); - template - static HasMerge Check(CheckType*); - template - static HasNoMerge Check(...); - - // Resolves to either std::true_type or std::false_type. - typedef std::integral_constant(0)) == sizeof(HasMerge))> - type; -}; - -template -struct TypeImplementsMergeBehavior - : TypeImplementsMergeBehaviorProbeForMergeFrom {}; - - -template <> -struct TypeImplementsMergeBehavior { - typedef std::true_type type; -}; - template struct IsMovable : std::integral_constant::value && @@ -177,12 +131,12 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { constexpr RepeatedPtrFieldBase() : tagged_rep_or_elem_(nullptr), current_size_(0), - total_size_(kSSOCapacity), + capacity_proxy_(0), arena_(nullptr) {} explicit RepeatedPtrFieldBase(Arena* arena) : tagged_rep_or_elem_(nullptr), current_size_(0), - total_size_(kSSOCapacity), + capacity_proxy_(0), arena_(arena) {} RepeatedPtrFieldBase(const RepeatedPtrFieldBase&) = delete; @@ -198,7 +152,13 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { bool empty() const { return current_size_ == 0; } int size() const { return current_size_; } - int Capacity() const { return total_size_; } + // Returns the size of the buffer with pointers to elements. + // + // Note: + // + // * prefer `SizeAtCapacity()` to `size() == Capacity()`; + // * prefer `AllocatedSizeAtCapacity()` to `allocated_size() == Capacity()`. + int Capacity() const { return capacity_proxy_ + kSSOCapacity; } template const Value& at(int index) const { @@ -223,17 +183,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { template Value* Add() { - return cast(AddOutOfLineHelper(NewT>)); - } - - template - Value* Add(const Value* prototype) { - if (current_size_ < allocated_size()) { - return cast( - element_at(ExchangeCurrentSize(current_size_ + 1))); - } - auto* result = TypeHandler::NewFromPrototype(prototype, arena_); - return cast(AddOutOfLineHelper(result)); + return cast(AddOutOfLineHelper(Handler::GetNewFunc())); } template < @@ -251,19 +201,18 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { element_at(ExchangeCurrentSize(current_size_ + 1)) = result; } - template - void Delete(int index) { - ABSL_DCHECK_GE(index, 0); - ABSL_DCHECK_LT(index, current_size_); - using H = CommonHandler; - Delete(element_at(index), arena_); - } - // Must be called from destructor. + // + // Pre-condition: NeedsDestroy() returns true. template void Destroy() { + ABSL_DCHECK(NeedsDestroy()); + + // TODO: arena check is redundant once all `RepeatedPtrField`s + // with non-null arena are owned by the arena. + if (PROTOBUF_PREDICT_FALSE(arena_ != nullptr)) return; + using H = CommonHandler; - if (arena_ != nullptr) return; int n = allocated_size(); void** elems = elements(); for (int i = 0; i < n; i++) { @@ -271,14 +220,16 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { } if (!using_sso()) { internal::SizedDelete(rep(), - total_size_ * sizeof(elems[0]) + kRepHeaderSize); + Capacity() * sizeof(elems[0]) + kRepHeaderSize); } } - bool NeedsDestroy() const { - return tagged_rep_or_elem_ != nullptr && arena_ == nullptr; + inline bool NeedsDestroy() const { + // Either there is an allocated element in SSO buffer or there is an + // allocated Rep. + return tagged_rep_or_elem_ != nullptr; } - void DestroyProtos(); // implemented in the cc file + void DestroyProtos(); public: // The next few methods are public so that they can be called from generated @@ -293,10 +244,10 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { } // Creates and adds an element using the given prototype, without introducing - // a link-time dependency on the concrete message type. This method is used to - // implement implicit weak fields. The prototype may be nullptr, in which case - // an ImplicitWeakMessage will be used as a placeholder. - MessageLite* AddWeak(const MessageLite* prototype); + // a link-time dependency on the concrete message type. + // + // Pre-condition: prototype must not be nullptr. + MessageLite* AddMessage(const MessageLite* prototype); template void Clear() { @@ -308,17 +259,17 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { } } - // Message creating functor: used in MergeFrom() - template - static MessageLite* CopyMessage(Arena* arena, const MessageLite& src) { - return Arena::CreateMaybeMessage(arena, static_cast(src)); - } - // Appends all message values from `from` to this instance. template void MergeFrom(const RepeatedPtrFieldBase& from) { static_assert(std::is_base_of::value, ""); - MergeFromConcreteMessage(from, CopyMessage); +#ifdef __cpp_if_constexpr + if constexpr (!std::is_base_of::value) { + // For LITE objects we use the generic MergeFrom to save on binary size. + return MergeFrom(from); + } +#endif + MergeFromConcreteMessage(from, Arena::CopyConstruct); } inline void InternalSwap(RepeatedPtrFieldBase* PROTOBUF_RESTRICT rhs) { @@ -417,7 +368,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { size_t allocated_bytes = using_sso() ? 0 - : static_cast(total_size_) * sizeof(void*) + kRepHeaderSize; + : static_cast(Capacity()) * sizeof(void*) + kRepHeaderSize; const int n = allocated_size(); void* const* elems = elements(); for (int i = 0; i < n; ++i) { @@ -442,20 +393,35 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { template void AddAllocated(Value* value) { - typename TypeImplementsMergeBehavior>::type t; ABSL_DCHECK_NE(value, nullptr); - AddAllocatedInternal(value, t); + Arena* element_arena = TypeHandler::GetArena(value); + Arena* arena = GetArena(); + if (arena != element_arena || AllocatedSizeAtCapacity()) { + AddAllocatedSlowWithCopy(value, element_arena, arena); + return; + } + // Fast path: underlying arena representation (tagged pointer) is equal to + // our arena pointer, and we can add to array without resizing it (at + // least one slot that is not allocated). + void** elems = elements(); + if (current_size_ < allocated_size()) { + // Make space at [current] by moving first allocated element to end of + // allocated list. + elems[allocated_size()] = elems[current_size_]; + } + elems[ExchangeCurrentSize(current_size_ + 1)] = value; + if (!using_sso()) ++rep()->allocated_size; } template void UnsafeArenaAddAllocated(Value* value) { ABSL_DCHECK_NE(value, nullptr); // Make room for the new pointer. - if (current_size_ == total_size_) { + if (SizeAtCapacity()) { // The array is completely full with no cleared objects, so grow it. - Reserve(total_size_ + 1); + InternalExtend(1); ++rep()->allocated_size; - } else if (allocated_size() == total_size_) { + } else if (AllocatedSizeAtCapacity()) { // There is no more space in the pointer array because it contains some // cleared objects awaiting reuse. We don't want to grow the array in // this case because otherwise a loop calling AddAllocated() followed by @@ -477,8 +443,17 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { template PROTOBUF_NODISCARD Value* ReleaseLast() { - typename TypeImplementsMergeBehavior>::type t; - return ReleaseLastInternal(t); + Value* result = UnsafeArenaReleaseLast(); + // Now perform a copy if we're on an arena. + Arena* arena = GetArena(); + +#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE + auto* new_result = copy(result); + if (arena == nullptr) delete result; +#else // PROTOBUF_FORCE_COPY_IN_RELEASE + auto* new_result = (arena == nullptr) ? result : copy(result); +#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE + return new_result; } // Releases and returns the last element, but does not do out-of-arena copy. @@ -534,48 +509,6 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { } } - // AddAllocated version that implements arena-safe copying behavior. - template - void AddAllocatedInternal(Value* value, std::true_type) { - Arena* element_arena = TypeHandler::GetArena(value); - Arena* arena = GetArena(); - if (arena == element_arena && allocated_size() < total_size_) { - // Fast path: underlying arena representation (tagged pointer) is equal to - // our arena pointer, and we can add to array without resizing it (at - // least one slot that is not allocated). - void** elems = elements(); - if (current_size_ < allocated_size()) { - // Make space at [current] by moving first allocated element to end of - // allocated list. - elems[allocated_size()] = elems[current_size_]; - } - elems[ExchangeCurrentSize(current_size_ + 1)] = value; - if (!using_sso()) ++rep()->allocated_size; - } else { - AddAllocatedSlowWithCopy(value, element_arena, arena); - } - } - - // AddAllocated version that does not implement arena-safe copying behavior. - template - void AddAllocatedInternal(Value* value, std::false_type) { - if (allocated_size() < total_size_) { - // Fast path: underlying arena representation (tagged pointer) is equal to - // our arena pointer, and we can add to array without resizing it (at - // least one slot that is not allocated). - void** elems = elements(); - if (current_size_ < allocated_size()) { - // Make space at [current] by moving first allocated element to end of - // allocated list. - elems[allocated_size()] = elems[current_size_]; - } - elems[ExchangeCurrentSize(current_size_ + 1)] = value; - if (!using_sso()) ++rep()->allocated_size; - } else { - UnsafeArenaAddAllocated(value); - } - } - // Slowpath handles all cases, copying if necessary. template PROTOBUF_NOINLINE void AddAllocatedSlowWithCopy( @@ -598,36 +531,6 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { UnsafeArenaAddAllocated(value); } - template - Value* ReleaseLastInternal(std::true_type) { - // ReleaseLast() for types that implement merge/copy behavior. - // First, release an element. - Value* result = UnsafeArenaReleaseLast(); - // Now perform a copy if we're on an arena. - Arena* arena = GetArena(); - -#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE - auto* new_result = copy(result); - if (arena == nullptr) delete result; -#else // PROTOBUF_FORCE_COPY_IN_RELEASE - auto* new_result = (arena == nullptr) ? result : copy(result); -#endif // !PROTOBUF_FORCE_COPY_IN_RELEASE - return new_result; - } - - template - Value* ReleaseLastInternal(std::false_type) { - // ReleaseLast() for types that *do not* implement merge/copy behavior -- - // this is the same as UnsafeArenaReleaseLast(). Note that we - // ABSL_DCHECK-fail if we're on an arena, since the user really should - // implement the copy operation in this case. - ABSL_DCHECK(GetArena() == nullptr) - << "ReleaseLast() called on a RepeatedPtrField that is on an arena, " - << "with a type that does not implement MergeFrom. This is unsafe; " - << "please implement MergeFrom for your type."; - return UnsafeArenaReleaseLast(); - } - template PROTOBUF_NOINLINE void SwapFallback(RepeatedPtrFieldBase* other) { #ifdef PROTOBUF_FORCE_COPY_IN_SWAP @@ -645,7 +548,9 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { } this->CopyFrom(*other); other->InternalSwap(&temp); - temp.Destroy(); // Frees rep_ if `other` had no arena. + if (temp.NeedsDestroy()) { + temp.Destroy(); + } } // Gets the Arena on which this RepeatedPtrField stores its elements. @@ -697,7 +602,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { // This follows the `Arena::CreateMaybeMessage` signature so that the compiler // can have the inlined call into the out of line copy function(s) simply pass // the address of `Arena::CreateMaybeMessage` 'as is'. - using CopyFn = MessageLite* (*)(Arena*, const MessageLite&); + using CopyFn = void* (*)(Arena*, const void*); struct Rep { int allocated_size; @@ -715,6 +620,25 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { inline int ExchangeCurrentSize(int new_size) { return std::exchange(current_size_, new_size); } + inline bool SizeAtCapacity() const { + // Harden invariant size() <= allocated_size() <= Capacity(). + ABSL_DCHECK_LE(size(), allocated_size()); + ABSL_DCHECK_LE(allocated_size(), Capacity()); + // This is equivalent to `current_size_ == Capacity()`. + // Assuming `Capacity()` function is inlined, compiler is likely to optimize + // away "+ kSSOCapacity" and reduce it to "current_size_ > capacity_proxy_" + // which is an instruction less than "current_size_ == capacity_proxy_ + 1". + return current_size_ >= Capacity(); + } + inline bool AllocatedSizeAtCapacity() const { + // Harden invariant size() <= allocated_size() <= Capacity(). + ABSL_DCHECK_LE(size(), allocated_size()); + ABSL_DCHECK_LE(allocated_size(), Capacity()); + // This combines optimization mentioned in `SizeAtCapacity()` and simplifies + // `allocated_size()` in sso case. + return using_sso() ? (tagged_rep_or_elem_ != nullptr) + : rep()->allocated_size >= Capacity(); + } void* const* elements() const { return using_sso() ? &tagged_rep_or_elem_ : +rep()->elements; @@ -800,8 +724,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { // Ensures that capacity is big enough to store one more allocated element. inline void MaybeExtend() { - if (using_sso() ? (tagged_rep_or_elem_ != nullptr) - : (rep()->allocated_size == total_size_)) { + if (AllocatedSizeAtCapacity()) { ABSL_DCHECK_EQ(allocated_size(), Capacity()); InternalExtend(1); } else { @@ -812,19 +735,27 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { // Ensures that capacity is at least `n` elements. // Returns a pointer to the element directly beyond the last element. inline void** InternalReserve(int n) { - if (n <= total_size_) { + if (n <= Capacity()) { void** elements = using_sso() ? &tagged_rep_or_elem_ : rep()->elements; return elements + current_size_; } - return InternalExtend(n - total_size_); + return InternalExtend(n - Capacity()); } - // Internal helper for Add: adds "obj" as the next element in the - // array, including potentially resizing the array with Reserve if - // needed - void* AddOutOfLineHelper(void* obj); + // Internal helper for Add that keeps definition out-of-line. void* AddOutOfLineHelper(ElementFactory factory); + // Common implementation used by various Add* methods. `factory` is an object + // used to construct a new element unless there are spare cleared elements + // ready for reuse. Returns pointer to the new element. + // + // Note: avoid inlining this function in methods such as `Add()` as this would + // drastically increase binary size due to template instantiation and implicit + // inlining. Instead, use wrapper functions with out-of-line definition + // similar to `AddOutOfLineHelper`. + template + auto* AddInternal(F factory); + // A few notes on internal representation: // // We use an indirected approach, with struct Rep, to keep @@ -838,7 +769,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { // significant performance for memory-sensitive workloads. void* tagged_rep_or_elem_; int current_size_; - int total_size_; + int capacity_proxy_; // we store `capacity - kSSOCapacity` as an optimization Arena* arena_; }; @@ -869,8 +800,10 @@ class GenericTypeHandler { typedef GenericType Type; using Movable = IsMovable; + static constexpr auto GetNewFunc() { return Arena::DefaultConstruct; } + static inline GenericType* New(Arena* arena) { - return Arena::CreateMaybeMessage(arena); + return static_cast(Arena::DefaultConstruct(arena)); } static inline GenericType* New(Arena* arena, GenericType&& value) { return Arena::Create(arena, std::move(value)); @@ -929,14 +862,6 @@ template <> PROTOBUF_EXPORT void GenericTypeHandler::Merge( const MessageLite& from, MessageLite* to); -template <> -inline void GenericTypeHandler::Clear(std::string* value) { - value->clear(); -} -template <> -void GenericTypeHandler::Merge(const std::string& from, - std::string* to); - // Message specialization bodies defined in message.cc. This split is necessary // to allow proto2-lite (which includes this header) to be independent of // Message. @@ -946,11 +871,16 @@ PROTOBUF_EXPORT Message* GenericTypeHandler::NewFromPrototype( template <> PROTOBUF_EXPORT Arena* GenericTypeHandler::GetArena(Message* value); -class StringTypeHandler { +PROTOBUF_EXPORT void* NewStringElement(Arena* arena); + +template <> +class GenericTypeHandler { public: typedef std::string Type; using Movable = IsMovable; + static constexpr auto GetNewFunc() { return NewStringElement; } + static PROTOBUF_NOINLINE std::string* New(Arena* arena) { return Arena::Create(arena); } @@ -1035,12 +965,13 @@ class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { Element, decltype(*std::declval())>::value>::type> RepeatedPtrField(Iter begin, Iter end); - RepeatedPtrField(const RepeatedPtrField& other) - : RepeatedPtrField(nullptr, other) {} + RepeatedPtrField(const RepeatedPtrField& rhs) + : RepeatedPtrField(nullptr, rhs) {} RepeatedPtrField& operator=(const RepeatedPtrField& other) ABSL_ATTRIBUTE_LIFETIME_BOUND; - RepeatedPtrField(RepeatedPtrField&& other) noexcept; + RepeatedPtrField(RepeatedPtrField&& rhs) noexcept + : RepeatedPtrField(nullptr, std::move(rhs)) {} RepeatedPtrField& operator=(RepeatedPtrField&& other) noexcept ABSL_ATTRIBUTE_LIFETIME_BOUND; @@ -1247,26 +1178,6 @@ class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { ABSL_DEPRECATED("This will be removed in a future release") int ClearedCount() const; -#ifndef PROTOBUF_FUTURE_REMOVE_CLEARED_API - // Adds an element to the pool of cleared objects, passing ownership to - // the RepeatedPtrField. The element must be cleared prior to calling - // this method. - // - // This method cannot be called when either the repeated field or |value| is - // on an arena; both cases will trigger a ABSL_DCHECK-failure. - ABSL_DEPRECATED("This will be removed in a future release") - void AddCleared(Element* value); - // Removes and returns a single element from the cleared pool, passing - // ownership to the caller. The element is guaranteed to be cleared. - // Requires: ClearedCount() > 0 - // - // This method cannot be called when the repeated field is on an arena; doing - // so will trigger a ABSL_DCHECK-failure. - PROTOBUF_NODISCARD - ABSL_DEPRECATED("This will be removed in a future release") - pointer ReleaseCleared(); -#endif // !PROTOBUF_FUTURE_REMOVE_CLEARED_API - // Removes the element referenced by position. // // Returns an iterator to the element immediately following the removed @@ -1311,20 +1222,12 @@ class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { friend struct WeakRepeatedPtrField; // Note: RepeatedPtrField SHOULD NOT be subclassed by users. - class TypeHandler; + using TypeHandler = internal::GenericTypeHandler; RepeatedPtrField(Arena* arena, const RepeatedPtrField& rhs); + RepeatedPtrField(Arena* arena, RepeatedPtrField&& rhs); - // Implementations for ExtractSubrange(). The copying behavior must be - // included only if the type supports the necessary operations (e.g., - // MergeFrom()), so we must resolve this at compile time. ExtractSubrange() - // uses SFINAE to choose one of the below implementations. - void ExtractSubrangeInternal(int start, int num, Element** elements, - std::true_type); - void ExtractSubrangeInternal(int start, int num, Element** elements, - std::false_type); - void AddAllocatedForParse(Element* p) { return RepeatedPtrFieldBase::AddAllocatedForParse(p); } @@ -1332,14 +1235,6 @@ class RepeatedPtrField final : private internal::RepeatedPtrFieldBase { // ------------------------------------------------------------------- -template -class RepeatedPtrField::TypeHandler - : public internal::GenericTypeHandler {}; - -template <> -class RepeatedPtrField::TypeHandler - : public internal::StringTypeHandler {}; - template constexpr RepeatedPtrField::RepeatedPtrField() : RepeatedPtrFieldBase() { @@ -1351,7 +1246,7 @@ inline RepeatedPtrField::RepeatedPtrField(Arena* arena) : RepeatedPtrFieldBase(arena) { // We can't have StaticValidityCheck here because that requires Element to be // a complete type, and in split repeated fields cases, we call - // CreateMaybeMessage> for incomplete Ts. + // CreateMessage> for incomplete Ts. } template @@ -1372,12 +1267,13 @@ inline RepeatedPtrField::RepeatedPtrField(Iter begin, Iter end) { template RepeatedPtrField::~RepeatedPtrField() { StaticValidityCheck(); + if (!NeedsDestroy()) return; #ifdef __cpp_if_constexpr if constexpr (std::is_base_of::value) { #else if (std::is_base_of::value) { #endif - if (NeedsDestroy()) DestroyProtos(); + DestroyProtos(); } else { Destroy(); } @@ -1391,19 +1287,18 @@ inline RepeatedPtrField& RepeatedPtrField::operator=( } template -inline RepeatedPtrField::RepeatedPtrField( - RepeatedPtrField&& other) noexcept - : RepeatedPtrField() { +inline RepeatedPtrField::RepeatedPtrField(Arena* arena, + RepeatedPtrField&& rhs) + : RepeatedPtrField(arena) { #ifdef PROTOBUF_FORCE_COPY_IN_MOVE - CopyFrom(other); + CopyFrom(rhs); #else // PROTOBUF_FORCE_COPY_IN_MOVE - // We don't just call Swap(&other) here because it would perform 3 copies if - // other is on an arena. This field can't be on an arena because arena - // construction always uses the Arena* accepting constructor. - if (other.GetArena()) { - CopyFrom(other); + // We don't just call Swap(&rhs) here because it would perform 3 copies if rhs + // is on a different arena. + if (arena != rhs.GetArena()) { + CopyFrom(rhs); } else { - InternalSwap(&other); + InternalSwap(&rhs); } #endif // !PROTOBUF_FORCE_COPY_IN_MOVE } @@ -1509,16 +1404,6 @@ inline void RepeatedPtrField::DeleteSubrange(int start, int num) { template inline void RepeatedPtrField::ExtractSubrange(int start, int num, Element** elements) { - typename internal::TypeImplementsMergeBehavior< - typename TypeHandler::Type>::type t; - ExtractSubrangeInternal(start, num, elements, t); -} - -// ExtractSubrange() implementation for types that implement merge/copy -// behavior. -template -inline void RepeatedPtrField::ExtractSubrangeInternal( - int start, int num, Element** elements, std::true_type) { ABSL_DCHECK_GE(start, 0); ABSL_DCHECK_GE(num, 0); ABSL_DCHECK_LE(start + num, size()); @@ -1556,21 +1441,6 @@ inline void RepeatedPtrField::ExtractSubrangeInternal( CloseGap(start, num); } -// ExtractSubrange() implementation for types that do not implement merge/copy -// behavior. -template -inline void RepeatedPtrField::ExtractSubrangeInternal( - int start, int num, Element** elements, std::false_type) { - // This case is identical to UnsafeArenaExtractSubrange(). However, since - // ExtractSubrange() must return heap-allocated objects by contract, and we - // cannot fulfill this contract if we are an on arena, we must ABSL_DCHECK() - // that we are not on an arena. - ABSL_DCHECK(GetArena() == nullptr) - << "ExtractSubrange() when arena is non-nullptr is only supported when " - << "the Element type supplies a MergeFrom() operation to make copies."; - UnsafeArenaExtractSubrange(start, num, elements); -} - template inline void RepeatedPtrField::UnsafeArenaExtractSubrange( int start, int num, Element** elements) { @@ -1707,18 +1577,6 @@ inline int RepeatedPtrField::ClearedCount() const { return RepeatedPtrFieldBase::ClearedCount(); } -#ifndef PROTOBUF_FUTURE_REMOVE_CLEARED_API -template -inline void RepeatedPtrField::AddCleared(Element* value) { - return RepeatedPtrFieldBase::AddCleared(value); -} - -template -inline Element* RepeatedPtrField::ReleaseCleared() { - return RepeatedPtrFieldBase::ReleaseCleared(); -} -#endif // !PROTOBUF_FUTURE_REMOVE_CLEARED_API - template inline void RepeatedPtrField::Reserve(int new_size) { return RepeatedPtrFieldBase::Reserve(new_size); @@ -1841,6 +1699,17 @@ class RepeatedPtrIterator { void* const* it_; }; +template +struct IteratorConceptSupport { + using tag = typename Traits::iterator_category; +}; + +template +struct IteratorConceptSupport> { + using tag = typename Traits::iterator_concept; +}; + // Provides an iterator that operates on pointers to the underlying objects // rather than the objects themselves as RepeatedPtrIterator does. // Consider using this when working with stl algorithms that change @@ -1850,13 +1719,19 @@ class RepeatedPtrIterator { // iterator, or "const void* const" for a constant iterator. template class RepeatedPtrOverPtrsIterator { + private: + using traits = + std::iterator_traits::type*>; + public: - using iterator = RepeatedPtrOverPtrsIterator; - using iterator_category = std::random_access_iterator_tag; - using value_type = typename std::remove_const::type; - using difference_type = std::ptrdiff_t; + using value_type = typename traits::value_type; + using difference_type = typename traits::difference_type; using pointer = Element*; using reference = Element&; + using iterator_category = typename traits::iterator_category; + using iterator_concept = typename IteratorConceptSupport::tag; + + using iterator = RepeatedPtrOverPtrsIterator; RepeatedPtrOverPtrsIterator() : it_(nullptr) {} explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {} diff --git a/src/google/protobuf/serial_arena.h b/src/google/protobuf/serial_arena.h index 743965f787..311c1dd3bb 100644 --- a/src/google/protobuf/serial_arena.h +++ b/src/google/protobuf/serial_arena.h @@ -88,6 +88,9 @@ struct FirstSerialArena { // used. class PROTOBUF_EXPORT SerialArena { public: + static constexpr size_t kBlockHeaderSize = + ArenaAlignDefault::Ceil(sizeof(ArenaBlock)); + void CleanupList(); size_t FreeStringBlocks() { // On the active block delete all strings skipping the unused instances. @@ -273,6 +276,24 @@ class PROTOBUF_EXPORT SerialArena { std::vector PeekCleanupListForTesting(); private: + friend class ThreadSafeArena; + + // See comments for cached_blocks_. + struct CachedBlock { + // Simple linked list. + CachedBlock* next; + }; + + static constexpr ptrdiff_t kPrefetchForwardsDegree = ABSL_CACHELINE_SIZE * 16; + static constexpr ptrdiff_t kPrefetchBackwardsDegree = ABSL_CACHELINE_SIZE * 6; + + // Constructor is private as only New() should be used. + inline SerialArena(ArenaBlock* b, ThreadSafeArena& parent); + + // Constructors to handle the first SerialArena. + inline explicit SerialArena(ThreadSafeArena& parent); + inline SerialArena(FirstSerialArena, ArenaBlock* b, ThreadSafeArena& parent); + bool MaybeAllocateString(void*& p); ABSL_ATTRIBUTE_RETURNS_NONNULL void* AllocateFromStringBlockFallback(); @@ -288,9 +309,6 @@ class PROTOBUF_EXPORT SerialArena { cleanup::CreateNode(tag, limit_, elem, destructor); } - static constexpr ptrdiff_t kPrefetchForwardsDegree = ABSL_CACHELINE_SIZE * 16; - static constexpr ptrdiff_t kPrefetchBackwardsDegree = ABSL_CACHELINE_SIZE * 6; - // Prefetch the next kPrefetchForwardsDegree bytes after `prefetch_ptr_` and // up to `prefetch_limit_`, if `next` is within kPrefetchForwardsDegree bytes // of `prefetch_ptr_`. @@ -335,9 +353,6 @@ class PROTOBUF_EXPORT SerialArena { } } - private: - friend class ThreadSafeArena; - // Creates a new SerialArena inside mem using the remaining memory as for // future allocations. // The `parent` arena must outlive the serial arena, which is guaranteed @@ -362,6 +377,29 @@ class PROTOBUF_EXPORT SerialArena { std::memory_order_relaxed); } + // Helper getters/setters to handle relaxed operations on atomic variables. + ArenaBlock* head() { return head_.load(std::memory_order_relaxed); } + const ArenaBlock* head() const { + return head_.load(std::memory_order_relaxed); + } + + char* ptr() { return ptr_.load(std::memory_order_relaxed); } + const char* ptr() const { return ptr_.load(std::memory_order_relaxed); } + void set_ptr(char* ptr) { return ptr_.store(ptr, std::memory_order_relaxed); } + PROTOBUF_ALWAYS_INLINE void set_range(char* ptr, char* limit) { + set_ptr(ptr); + prefetch_ptr_ = ptr; + limit_ = limit; + prefetch_limit_ = limit; + } + + void* AllocateAlignedFallback(size_t n); + void* AllocateAlignedWithCleanupFallback(size_t n, size_t align, + void (*destructor)(void*)); + void AddCleanupFallback(void* elem, void (*destructor)(void*)); + inline void AllocateNewBlock(size_t n); + inline void Init(ArenaBlock* b, size_t offset); + // Members are declared here to track sizeof(SerialArena) and hotness // centrally. They are (roughly) laid out in descending order of hotness. @@ -397,46 +435,8 @@ class PROTOBUF_EXPORT SerialArena { // this free list. // `cached_blocks_[i]` points to the free list for blocks of size `8+2^(i+3)`. // The array of freelists is grown when needed in `ReturnArrayMemory()`. - struct CachedBlock { - // Simple linked list. - CachedBlock* next; - }; uint8_t cached_block_length_ = 0; CachedBlock** cached_blocks_ = nullptr; - - // Helper getters/setters to handle relaxed operations on atomic variables. - ArenaBlock* head() { return head_.load(std::memory_order_relaxed); } - const ArenaBlock* head() const { - return head_.load(std::memory_order_relaxed); - } - - char* ptr() { return ptr_.load(std::memory_order_relaxed); } - const char* ptr() const { return ptr_.load(std::memory_order_relaxed); } - void set_ptr(char* ptr) { return ptr_.store(ptr, std::memory_order_relaxed); } - PROTOBUF_ALWAYS_INLINE void set_range(char* ptr, char* limit) { - set_ptr(ptr); - prefetch_ptr_ = ptr; - limit_ = limit; - prefetch_limit_ = limit; - } - - // Constructor is private as only New() should be used. - inline SerialArena(ArenaBlock* b, ThreadSafeArena& parent); - - // Constructors to handle the first SerialArena. - inline explicit SerialArena(ThreadSafeArena& parent); - inline SerialArena(FirstSerialArena, ArenaBlock* b, ThreadSafeArena& parent); - - void* AllocateAlignedFallback(size_t n); - void* AllocateAlignedWithCleanupFallback(size_t n, size_t align, - void (*destructor)(void*)); - void AddCleanupFallback(void* elem, void (*destructor)(void*)); - inline void AllocateNewBlock(size_t n); - inline void Init(ArenaBlock* b, size_t offset); - - public: - static constexpr size_t kBlockHeaderSize = - ArenaAlignDefault::Ceil(sizeof(ArenaBlock)); }; inline PROTOBUF_ALWAYS_INLINE bool SerialArena::MaybeAllocateString(void*& p) { diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc index b93bf206fa..3375db2f26 100644 --- a/src/google/protobuf/source_context.pb.cc +++ b/src/google/protobuf/source_context.pb.cc @@ -1,5 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/source_context.proto +// Protobuf C++ Version: 4.26.0-dev #include "google/protobuf/source_context.pb.h" @@ -114,9 +115,6 @@ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fsource_5fcont PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto; } -// Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 -static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fsource_5fcontext_2eproto(&descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto); namespace google { namespace protobuf { // =================================================================== @@ -171,12 +169,13 @@ inline void SourceContext::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* SourceContext::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { SourceContext::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(SourceContext, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void SourceContext::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.SourceContext) @@ -210,6 +209,9 @@ const ::_pbi::TcParseTable<0, 1, 0, 47, 2> SourceContext::_table_ = { offsetof(decltype(_table_), field_names), // no aux_entries &_SourceContext_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::SourceContext>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // string file_name = 1; {::_pbi::TcParser::FastUS1, @@ -271,7 +273,7 @@ const ::_pbi::TcParseTable<0, 1, 0, 47, 2> SourceContext::_table_ = { } -void SourceContext::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void SourceContext::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceContext) @@ -296,9 +298,6 @@ PROTOBUF_NOINLINE bool SourceContext::IsInitialized() const { return true; } -::_pbi::CachedSize* SourceContext::AccessCachedSize() const { - return &_impl_._cached_size_; -} void SourceContext::InternalSwap(SourceContext* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -308,9 +307,9 @@ void SourceContext::InternalSwap(SourceContext* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata SourceContext::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_getter, &descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_once, - file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto[0]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto_once, + file_level_metadata_google_2fprotobuf_2fsource_5fcontext_2eproto[0]); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf @@ -320,4 +319,8 @@ namespace protobuf { } // namespace protobuf } // namespace google // @@protoc_insertion_point(global_scope) +PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 +static ::std::false_type _static_init_ PROTOBUF_UNUSED = + (::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto), + ::std::false_type{}); #include "google/protobuf/port_undef.inc" diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h index ed58fe7fcf..be61ddf335 100644 --- a/src/google/protobuf/source_context.pb.h +++ b/src/google/protobuf/source_context.pb.h @@ -1,6 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/source_context.proto -// Protobuf C++ Version: 4.24.0-main +// Protobuf C++ Version: 4.26.0-dev #ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fsource_5fcontext_2eproto_2epb_2eh #define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fsource_5fcontext_2eproto_2epb_2eh @@ -11,17 +11,11 @@ #include #include "google/protobuf/port_def.inc" -#if PROTOBUF_VERSION < 4024000 -#error "This file was generated by a newer version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please update" -#error "your headers." -#endif // PROTOBUF_VERSION - -#if 4024000 < PROTOBUF_MIN_PROTOC_VERSION -#error "This file was generated by an older version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please" -#error "regenerate this file with a newer version of protoc." -#endif // PROTOBUF_MIN_PROTOC_VERSION +#if PROTOBUF_VERSION != 4026000 +#error "Protobuf C++ gencode is built with an incompatible version of" +#error "Protobuf C++ headers/runtime. See" +#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp" +#endif #include "google/protobuf/port_undef.inc" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/arena.h" @@ -71,21 +65,18 @@ namespace protobuf { // ------------------------------------------------------------------- -class PROTOBUF_EXPORT SourceContext final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.SourceContext) */ { +class PROTOBUF_EXPORT SourceContext final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.SourceContext) */ { public: inline SourceContext() : SourceContext(nullptr) {} ~SourceContext() override; - template - explicit PROTOBUF_CONSTEXPR SourceContext(::google::protobuf::internal::ConstantInitialized); - - inline SourceContext(const SourceContext& from) - : SourceContext(nullptr, from) {} - SourceContext(SourceContext&& from) noexcept - : SourceContext() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR SourceContext( + ::google::protobuf::internal::ConstantInitialized); + inline SourceContext(const SourceContext& from) : SourceContext(nullptr, from) {} + inline SourceContext(SourceContext&& from) noexcept + : SourceContext(nullptr, std::move(from)) {} inline SourceContext& operator=(const SourceContext& from) { CopyFrom(from); return *this; @@ -93,9 +84,9 @@ class PROTOBUF_EXPORT SourceContext final : inline SourceContext& operator=(SourceContext&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -127,22 +118,17 @@ class PROTOBUF_EXPORT SourceContext final : } static inline const SourceContext* internal_default_instance() { return reinterpret_cast( - &_SourceContext_default_instance_); - } - static constexpr int kIndexInFileMessages = - 0; - - friend void swap(SourceContext& a, SourceContext& b) { - a.Swap(&b); + &_SourceContext_default_instance_); } + static constexpr int kIndexInFileMessages = 0; + friend void swap(SourceContext& a, SourceContext& b) { a.Swap(&b); } inline void Swap(SourceContext* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -157,16 +143,18 @@ class PROTOBUF_EXPORT SourceContext final : // implements Message ---------------------------------------------- SourceContext* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const SourceContext& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const SourceContext& from) { - SourceContext::MergeImpl(*this, from); - } + void MergeFrom(const SourceContext& from) { SourceContext::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -174,32 +162,33 @@ class PROTOBUF_EXPORT SourceContext final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(SourceContext* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.SourceContext"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.SourceContext"; } + + protected: explicit SourceContext(::google::protobuf::Arena* arena); SourceContext(::google::protobuf::Arena* arena, const SourceContext& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + SourceContext(::google::protobuf::Arena* arena, SourceContext&& from) noexcept + : SourceContext(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kFileNameFieldNumber = 1, }; @@ -222,7 +211,6 @@ class PROTOBUF_EXPORT SourceContext final : // @@protoc_insertion_point(class_scope:google.protobuf.SourceContext) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 0, 1, 0, @@ -234,14 +222,13 @@ class PROTOBUF_EXPORT SourceContext final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::ArenaStringPtr file_name_; mutable ::google::protobuf::internal::CachedSize _cached_size_; PROTOBUF_TSAN_DECLARE_MEMBER @@ -280,7 +267,6 @@ template inline PROTOBUF_ALWAYS_INLINE void SourceContext::set_file_name(Arg_&& arg, Args_... args) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.file_name_.Set(static_cast(arg), args..., GetArena()); // @@protoc_insertion_point(field_set:google.protobuf.SourceContext.file_name) } @@ -295,12 +281,10 @@ inline const std::string& SourceContext::_internal_file_name() const { } inline void SourceContext::_internal_set_file_name(const std::string& value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.file_name_.Set(value, GetArena()); } inline std::string* SourceContext::_internal_mutable_file_name() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; return _impl_.file_name_.Mutable( GetArena()); } inline std::string* SourceContext::release_file_name() { diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc index cb8e5c9736..429018c61d 100644 --- a/src/google/protobuf/struct.pb.cc +++ b/src/google/protobuf/struct.pb.cc @@ -1,5 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/struct.proto +// Protobuf C++ Version: 4.26.0-dev #include "google/protobuf/struct.pb.h" @@ -214,9 +215,6 @@ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fstruct_2eprot PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2fstruct_2eproto; } -// Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 -static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fstruct_2eproto(&descriptor_table_google_2fprotobuf_2fstruct_2eproto); namespace google { namespace protobuf { const ::google::protobuf::EnumDescriptor* NullValue_descriptor() { @@ -234,9 +232,9 @@ Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse() {} Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse(::google::protobuf::Arena* arena) : SuperType(arena) {} ::google::protobuf::Metadata Struct_FieldsEntry_DoNotUse::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once, - file_level_metadata_google_2fprotobuf_2fstruct_2eproto[0]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once, + file_level_metadata_google_2fprotobuf_2fstruct_2eproto[0]); } // =================================================================== @@ -289,12 +287,13 @@ inline void Struct::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* Struct::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { Struct::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(Struct, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void Struct::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Struct) @@ -328,6 +327,9 @@ const ::_pbi::TcParseTable<0, 1, 2, 37, 2> Struct::_table_ = { offsetof(decltype(_table_), aux_entries), &_Struct_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::Struct>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, }}, {{ @@ -411,7 +413,7 @@ const ::_pbi::TcParseTable<0, 1, 2, 37, 2> Struct::_table_ = { } -void Struct::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void Struct::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Struct) @@ -434,9 +436,6 @@ PROTOBUF_NOINLINE bool Struct::IsInitialized() const { return true; } -::_pbi::CachedSize* Struct::AccessCachedSize() const { - return &_impl_._cached_size_; -} void Struct::InternalSwap(Struct* PROTOBUF_RESTRICT other) { using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); @@ -444,9 +443,9 @@ void Struct::InternalSwap(Struct* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata Struct::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once, - file_level_metadata_google_2fprotobuf_2fstruct_2eproto[1]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once, + file_level_metadata_google_2fprotobuf_2fstruct_2eproto[1]); } // =================================================================== @@ -454,16 +453,8 @@ class Value::_Internal { public: static constexpr ::int32_t kOneofCaseOffset = PROTOBUF_FIELD_OFFSET(::google::protobuf::Value, _impl_._oneof_case_); - static const ::google::protobuf::Struct& struct_value(const Value* msg); - static const ::google::protobuf::ListValue& list_value(const Value* msg); }; -const ::google::protobuf::Struct& Value::_Internal::struct_value(const Value* msg) { - return *msg->_impl_.kind_.struct_value_; -} -const ::google::protobuf::ListValue& Value::_Internal::list_value(const Value* msg) { - return *msg->_impl_.kind_.list_value_; -} void Value::set_allocated_struct_value(::google::protobuf::Struct* struct_value) { ::google::protobuf::Arena* message_arena = GetArena(); clear_kind(); @@ -527,10 +518,10 @@ Value::Value( _impl_.kind_.bool_value_ = from._impl_.kind_.bool_value_; break; case kStructValue: - _impl_.kind_.struct_value_ = CreateMaybeMessage<::google::protobuf::Struct>(arena, *from._impl_.kind_.struct_value_); + _impl_.kind_.struct_value_ = ::google::protobuf::Message::CopyConstruct<::google::protobuf::Struct>(arena, *from._impl_.kind_.struct_value_); break; case kListValue: - _impl_.kind_.list_value_ = CreateMaybeMessage<::google::protobuf::ListValue>(arena, *from._impl_.kind_.list_value_); + _impl_.kind_.list_value_ = ::google::protobuf::Message::CopyConstruct<::google::protobuf::ListValue>(arena, *from._impl_.kind_.list_value_); break; } @@ -602,12 +593,13 @@ void Value::clear_kind() { const ::google::protobuf::MessageLite::ClassData* Value::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { Value::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(Value, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void Value::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Value) @@ -641,6 +633,9 @@ const ::_pbi::TcParseTable<0, 6, 2, 42, 2> Value::_table_ = { offsetof(decltype(_table_), aux_entries), &_Value_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::Value>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, }}, {{ @@ -709,14 +704,12 @@ const ::_pbi::TcParseTable<0, 6, 2, 42, 2> Value::_table_ = { } case kStructValue: { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 5, _Internal::struct_value(this), - _Internal::struct_value(this).GetCachedSize(), target, stream); + 5, *_impl_.kind_.struct_value_, _impl_.kind_.struct_value_->GetCachedSize(), target, stream); break; } case kListValue: { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 6, _Internal::list_value(this), - _Internal::list_value(this).GetCachedSize(), target, stream); + 6, *_impl_.kind_.list_value_, _impl_.kind_.list_value_->GetCachedSize(), target, stream); break; } default: @@ -782,43 +775,65 @@ const ::_pbi::TcParseTable<0, 6, 2, 42, 2> Value::_table_ = { } -void Value::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void Value::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Value) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; (void) cached_has_bits; - switch (from.kind_case()) { - case kNullValue: { - _this->_internal_set_null_value(from._internal_null_value()); - break; - } - case kNumberValue: { - _this->_internal_set_number_value(from._internal_number_value()); - break; - } - case kStringValue: { - _this->_internal_set_string_value(from._internal_string_value()); - break; - } - case kBoolValue: { - _this->_internal_set_bool_value(from._internal_bool_value()); - break; - } - case kStructValue: { - _this->_internal_mutable_struct_value()->::google::protobuf::Struct::MergeFrom( - from._internal_struct_value()); - break; - } - case kListValue: { - _this->_internal_mutable_list_value()->::google::protobuf::ListValue::MergeFrom( - from._internal_list_value()); - break; + if (const uint32_t oneof_from_case = from._impl_._oneof_case_[0]) { + const uint32_t oneof_to_case = _this->_impl_._oneof_case_[0]; + const bool oneof_needs_init = oneof_to_case != oneof_from_case; + if (oneof_needs_init) { + if (oneof_to_case != 0) { + _this->clear_kind(); + } + _this->_impl_._oneof_case_[0] = oneof_from_case; } - case KIND_NOT_SET: { - break; + + switch (oneof_from_case) { + case kNullValue: { + _this->_impl_.kind_.null_value_ = from._impl_.kind_.null_value_; + break; + } + case kNumberValue: { + _this->_impl_.kind_.number_value_ = from._impl_.kind_.number_value_; + break; + } + case kStringValue: { + if (oneof_needs_init) { + _this->_impl_.kind_.string_value_.InitDefault(); + } + _this->_impl_.kind_.string_value_.Set(from._internal_string_value(), arena); + break; + } + case kBoolValue: { + _this->_impl_.kind_.bool_value_ = from._impl_.kind_.bool_value_; + break; + } + case kStructValue: { + if (oneof_needs_init) { + _this->_impl_.kind_.struct_value_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::Struct>(arena, *from._impl_.kind_.struct_value_); + } else { + _this->_impl_.kind_.struct_value_->MergeFrom(from._internal_struct_value()); + } + break; + } + case kListValue: { + if (oneof_needs_init) { + _this->_impl_.kind_.list_value_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::ListValue>(arena, *from._impl_.kind_.list_value_); + } else { + _this->_impl_.kind_.list_value_->MergeFrom(from._internal_list_value()); + } + break; + } + case KIND_NOT_SET: + break; } } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); @@ -835,9 +850,6 @@ PROTOBUF_NOINLINE bool Value::IsInitialized() const { return true; } -::_pbi::CachedSize* Value::AccessCachedSize() const { - return &_impl_._cached_size_; -} void Value::InternalSwap(Value* PROTOBUF_RESTRICT other) { using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); @@ -846,9 +858,9 @@ void Value::InternalSwap(Value* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata Value::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once, - file_level_metadata_google_2fprotobuf_2fstruct_2eproto[2]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once, + file_level_metadata_google_2fprotobuf_2fstruct_2eproto[2]); } // =================================================================== @@ -901,12 +913,13 @@ inline void ListValue::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* ListValue::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { ListValue::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(ListValue, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void ListValue::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.ListValue) @@ -940,6 +953,9 @@ const ::_pbi::TcParseTable<0, 1, 1, 0, 2> ListValue::_table_ = { offsetof(decltype(_table_), aux_entries), &_ListValue_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::ListValue>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // repeated .google.protobuf.Value values = 1; {::_pbi::TcParser::FastMtR1, @@ -998,7 +1014,7 @@ const ::_pbi::TcParseTable<0, 1, 1, 0, 2> ListValue::_table_ = { } -void ListValue::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void ListValue::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ListValue) @@ -1022,9 +1038,6 @@ PROTOBUF_NOINLINE bool ListValue::IsInitialized() const { return true; } -::_pbi::CachedSize* ListValue::AccessCachedSize() const { - return &_impl_._cached_size_; -} void ListValue::InternalSwap(ListValue* PROTOBUF_RESTRICT other) { using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); @@ -1032,9 +1045,9 @@ void ListValue::InternalSwap(ListValue* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata ListValue::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once, - file_level_metadata_google_2fprotobuf_2fstruct_2eproto[3]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fstruct_2eproto_getter, + &descriptor_table_google_2fprotobuf_2fstruct_2eproto_once, + file_level_metadata_google_2fprotobuf_2fstruct_2eproto[3]); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf @@ -1044,4 +1057,8 @@ namespace protobuf { } // namespace protobuf } // namespace google // @@protoc_insertion_point(global_scope) +PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 +static ::std::false_type _static_init_ PROTOBUF_UNUSED = + (::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2fstruct_2eproto), + ::std::false_type{}); #include "google/protobuf/port_undef.inc" diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h index 6f9c7d176e..0ac4a35bb0 100644 --- a/src/google/protobuf/struct.pb.h +++ b/src/google/protobuf/struct.pb.h @@ -1,6 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/struct.proto -// Protobuf C++ Version: 4.24.0-main +// Protobuf C++ Version: 4.26.0-dev #ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fstruct_2eproto_2epb_2eh #define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fstruct_2eproto_2epb_2eh @@ -11,17 +11,11 @@ #include #include "google/protobuf/port_def.inc" -#if PROTOBUF_VERSION < 4024000 -#error "This file was generated by a newer version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please update" -#error "your headers." -#endif // PROTOBUF_VERSION - -#if 4024000 < PROTOBUF_MIN_PROTOC_VERSION -#error "This file was generated by an older version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please" -#error "regenerate this file with a newer version of protoc." -#endif // PROTOBUF_MIN_PROTOC_VERSION +#if PROTOBUF_VERSION != 4026000 +#error "Protobuf C++ gencode is built with an incompatible version of" +#error "Protobuf C++ headers/runtime. See" +#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp" +#endif #include "google/protobuf/port_undef.inc" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/arena.h" @@ -116,21 +110,18 @@ inline bool NullValue_Parse(absl::string_view name, NullValue* value) { // ------------------------------------------------------------------- -class PROTOBUF_EXPORT ListValue final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.ListValue) */ { +class PROTOBUF_EXPORT ListValue final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.ListValue) */ { public: inline ListValue() : ListValue(nullptr) {} ~ListValue() override; - template - explicit PROTOBUF_CONSTEXPR ListValue(::google::protobuf::internal::ConstantInitialized); - - inline ListValue(const ListValue& from) - : ListValue(nullptr, from) {} - ListValue(ListValue&& from) noexcept - : ListValue() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR ListValue( + ::google::protobuf::internal::ConstantInitialized); + inline ListValue(const ListValue& from) : ListValue(nullptr, from) {} + inline ListValue(ListValue&& from) noexcept + : ListValue(nullptr, std::move(from)) {} inline ListValue& operator=(const ListValue& from) { CopyFrom(from); return *this; @@ -138,9 +129,9 @@ class PROTOBUF_EXPORT ListValue final : inline ListValue& operator=(ListValue&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -172,22 +163,17 @@ class PROTOBUF_EXPORT ListValue final : } static inline const ListValue* internal_default_instance() { return reinterpret_cast( - &_ListValue_default_instance_); - } - static constexpr int kIndexInFileMessages = - 3; - - friend void swap(ListValue& a, ListValue& b) { - a.Swap(&b); + &_ListValue_default_instance_); } + static constexpr int kIndexInFileMessages = 3; + friend void swap(ListValue& a, ListValue& b) { a.Swap(&b); } inline void Swap(ListValue* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -202,16 +188,18 @@ class PROTOBUF_EXPORT ListValue final : // implements Message ---------------------------------------------- ListValue* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const ListValue& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const ListValue& from) { - ListValue::MergeImpl(*this, from); - } + void MergeFrom(const ListValue& from) { ListValue::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -219,32 +207,33 @@ class PROTOBUF_EXPORT ListValue final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(ListValue* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.ListValue"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.ListValue"; } + + protected: explicit ListValue(::google::protobuf::Arena* arena); ListValue(::google::protobuf::Arena* arena, const ListValue& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + ListValue(::google::protobuf::Arena* arena, ListValue&& from) noexcept + : ListValue(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kValuesFieldNumber = 1, }; @@ -256,20 +245,18 @@ class PROTOBUF_EXPORT ListValue final : public: void clear_values() ; ::google::protobuf::Value* mutable_values(int index); - ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >* - mutable_values(); + ::google::protobuf::RepeatedPtrField<::google::protobuf::Value>* mutable_values(); + private: const ::google::protobuf::RepeatedPtrField<::google::protobuf::Value>& _internal_values() const; ::google::protobuf::RepeatedPtrField<::google::protobuf::Value>* _internal_mutable_values(); public: const ::google::protobuf::Value& values(int index) const; ::google::protobuf::Value* add_values(); - const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >& - values() const; + const ::google::protobuf::RepeatedPtrField<::google::protobuf::Value>& values() const; // @@protoc_insertion_point(class_scope:google.protobuf.ListValue) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 0, 1, 1, @@ -281,37 +268,34 @@ class PROTOBUF_EXPORT ListValue final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value > values_; mutable ::google::protobuf::internal::CachedSize _cached_size_; PROTOBUF_TSAN_DECLARE_MEMBER }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- -class PROTOBUF_EXPORT Struct final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Struct) */ { +class PROTOBUF_EXPORT Struct final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.Struct) */ { public: inline Struct() : Struct(nullptr) {} ~Struct() override; - template - explicit PROTOBUF_CONSTEXPR Struct(::google::protobuf::internal::ConstantInitialized); - - inline Struct(const Struct& from) - : Struct(nullptr, from) {} - Struct(Struct&& from) noexcept - : Struct() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR Struct( + ::google::protobuf::internal::ConstantInitialized); + inline Struct(const Struct& from) : Struct(nullptr, from) {} + inline Struct(Struct&& from) noexcept + : Struct(nullptr, std::move(from)) {} inline Struct& operator=(const Struct& from) { CopyFrom(from); return *this; @@ -319,9 +303,9 @@ class PROTOBUF_EXPORT Struct final : inline Struct& operator=(Struct&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -353,22 +337,17 @@ class PROTOBUF_EXPORT Struct final : } static inline const Struct* internal_default_instance() { return reinterpret_cast( - &_Struct_default_instance_); - } - static constexpr int kIndexInFileMessages = - 1; - - friend void swap(Struct& a, Struct& b) { - a.Swap(&b); + &_Struct_default_instance_); } + static constexpr int kIndexInFileMessages = 1; + friend void swap(Struct& a, Struct& b) { a.Swap(&b); } inline void Swap(Struct* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -383,16 +362,18 @@ class PROTOBUF_EXPORT Struct final : // implements Message ---------------------------------------------- Struct* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const Struct& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const Struct& from) { - Struct::MergeImpl(*this, from); - } + void MergeFrom(const Struct& from) { Struct::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -400,33 +381,33 @@ class PROTOBUF_EXPORT Struct final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(Struct* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.Struct"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.Struct"; } + + protected: explicit Struct(::google::protobuf::Arena* arena); Struct(::google::protobuf::Arena* arena, const Struct& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + Struct(::google::protobuf::Arena* arena, Struct&& from) noexcept + : Struct(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- - // accessors ------------------------------------------------------- - enum : int { kFieldsFieldNumber = 1, }; @@ -448,7 +429,6 @@ class PROTOBUF_EXPORT Struct final : // @@protoc_insertion_point(class_scope:google.protobuf.Struct) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 0, 1, 2, @@ -460,14 +440,13 @@ class PROTOBUF_EXPORT Struct final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::google::protobuf::internal::MapField @@ -477,7 +456,8 @@ class PROTOBUF_EXPORT Struct final : }; union { Impl_ _impl_; }; friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto; -};// ------------------------------------------------------------------- +}; +// ------------------------------------------------------------------- class Struct_FieldsEntry_DoNotUse final : public ::google::protobuf::internal::MapEntry< @@ -507,21 +487,18 @@ class Struct_FieldsEntry_DoNotUse final }; // ------------------------------------------------------------------- -class PROTOBUF_EXPORT Value final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Value) */ { +class PROTOBUF_EXPORT Value final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.Value) */ { public: inline Value() : Value(nullptr) {} ~Value() override; - template - explicit PROTOBUF_CONSTEXPR Value(::google::protobuf::internal::ConstantInitialized); - - inline Value(const Value& from) - : Value(nullptr, from) {} - Value(Value&& from) noexcept - : Value() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR Value( + ::google::protobuf::internal::ConstantInitialized); + inline Value(const Value& from) : Value(nullptr, from) {} + inline Value(Value&& from) noexcept + : Value(nullptr, std::move(from)) {} inline Value& operator=(const Value& from) { CopyFrom(from); return *this; @@ -529,9 +506,9 @@ class PROTOBUF_EXPORT Value final : inline Value& operator=(Value&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -570,25 +547,19 @@ class PROTOBUF_EXPORT Value final : kListValue = 6, KIND_NOT_SET = 0, }; - static inline const Value* internal_default_instance() { return reinterpret_cast( - &_Value_default_instance_); - } - static constexpr int kIndexInFileMessages = - 2; - - friend void swap(Value& a, Value& b) { - a.Swap(&b); + &_Value_default_instance_); } + static constexpr int kIndexInFileMessages = 2; + friend void swap(Value& a, Value& b) { a.Swap(&b); } inline void Swap(Value* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -603,16 +574,18 @@ class PROTOBUF_EXPORT Value final : // implements Message ---------------------------------------------- Value* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const Value& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const Value& from) { - Value::MergeImpl(*this, from); - } + void MergeFrom(const Value& from) { Value::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -620,32 +593,33 @@ class PROTOBUF_EXPORT Value final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(Value* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.Value"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.Value"; } + + protected: explicit Value(::google::protobuf::Arena* arena); Value(::google::protobuf::Arena* arena, const Value& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + Value(::google::protobuf::Arena* arena, Value&& from) noexcept + : Value(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kNullValueFieldNumber = 1, kNumberValueFieldNumber = 2, @@ -753,10 +727,8 @@ class PROTOBUF_EXPORT Value final : void set_has_bool_value(); void set_has_struct_value(); void set_has_list_value(); - inline bool has_kind() const; inline void clear_has_kind(); - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 0, 6, 2, @@ -768,17 +740,16 @@ class PROTOBUF_EXPORT Value final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); union KindUnion { constexpr KindUnion() : _constinit_{} {} - ::google::protobuf::internal::ConstantInitialized _constinit_; + ::google::protobuf::internal::ConstantInitialized _constinit_; int null_value_; double number_value_; ::google::protobuf::internal::ArenaStringPtr string_value_; @@ -788,7 +759,6 @@ class PROTOBUF_EXPORT Value final : } kind_; mutable ::google::protobuf::internal::CachedSize _cached_size_; ::uint32_t _oneof_case_[1]; - PROTOBUF_TSAN_DECLARE_MEMBER }; union { Impl_ _impl_; }; @@ -864,7 +834,11 @@ inline ::google::protobuf::NullValue Value::null_value() const { return _internal_null_value(); } inline void Value::set_null_value(::google::protobuf::NullValue value) { - _internal_set_null_value(value); + if (kind_case() != kNullValue) { + clear_kind(); + set_has_null_value(); + } + _impl_.kind_.null_value_ = value; // @@protoc_insertion_point(field_set:google.protobuf.Value.null_value) } inline ::google::protobuf::NullValue Value::_internal_null_value() const { @@ -873,13 +847,6 @@ inline ::google::protobuf::NullValue Value::_internal_null_value() const { } return static_cast<::google::protobuf::NullValue>(0); } -inline void Value::_internal_set_null_value(::google::protobuf::NullValue value) { - if (kind_case() != kNullValue) { - clear_kind(); - set_has_null_value(); - } - _impl_.kind_.null_value_ = value; -} // double number_value = 2; inline bool Value::has_number_value() const { @@ -900,7 +867,11 @@ inline double Value::number_value() const { return _internal_number_value(); } inline void Value::set_number_value(double value) { - _internal_set_number_value(value); + if (kind_case() != kNumberValue) { + clear_kind(); + set_has_number_value(); + } + _impl_.kind_.number_value_ = value; // @@protoc_insertion_point(field_set:google.protobuf.Value.number_value) } inline double Value::_internal_number_value() const { @@ -909,13 +880,6 @@ inline double Value::_internal_number_value() const { } return 0; } -inline void Value::_internal_set_number_value(double value) { - if (kind_case() != kNumberValue) { - clear_kind(); - set_has_number_value(); - } - _impl_.kind_.number_value_ = value; -} // string string_value = 3; inline bool Value::has_string_value() const { @@ -1021,7 +985,11 @@ inline bool Value::bool_value() const { return _internal_bool_value(); } inline void Value::set_bool_value(bool value) { - _internal_set_bool_value(value); + if (kind_case() != kBoolValue) { + clear_kind(); + set_has_bool_value(); + } + _impl_.kind_.bool_value_ = value; // @@protoc_insertion_point(field_set:google.protobuf.Value.bool_value) } inline bool Value::_internal_bool_value() const { @@ -1030,13 +998,6 @@ inline bool Value::_internal_bool_value() const { } return false; } -inline void Value::_internal_set_bool_value(bool value) { - if (kind_case() != kBoolValue) { - clear_kind(); - set_has_bool_value(); - } - _impl_.kind_.bool_value_ = value; -} // .google.protobuf.Struct struct_value = 5; inline bool Value::has_struct_value() const { @@ -1104,7 +1065,8 @@ inline ::google::protobuf::Struct* Value::_internal_mutable_struct_value() { if (kind_case() != kStructValue) { clear_kind(); set_has_struct_value(); - _impl_.kind_.struct_value_ = CreateMaybeMessage<::google::protobuf::Struct>(GetArena()); + _impl_.kind_.struct_value_ = + ::google::protobuf::Message::DefaultConstruct<::google::protobuf::Struct>(GetArena()); } return _impl_.kind_.struct_value_; } @@ -1180,7 +1142,8 @@ inline ::google::protobuf::ListValue* Value::_internal_mutable_list_value() { if (kind_case() != kListValue) { clear_kind(); set_has_list_value(); - _impl_.kind_.list_value_ = CreateMaybeMessage<::google::protobuf::ListValue>(GetArena()); + _impl_.kind_.list_value_ = + ::google::protobuf::Message::DefaultConstruct<::google::protobuf::ListValue>(GetArena()); } return _impl_.kind_.list_value_; } diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc index faff493a4e..3313150d15 100644 --- a/src/google/protobuf/stubs/common.cc +++ b/src/google/protobuf/stubs/common.cc @@ -41,38 +41,21 @@ namespace protobuf { namespace internal { -void VerifyVersion(int headerVersion, - int minLibraryVersion, - const char* filename) { - if (GOOGLE_PROTOBUF_VERSION < minLibraryVersion) { - // Library is too old for headers. +void VerifyVersion(int protobufVersionCompiledWith, const char* filename) { + // If the user's program is linked against a different version of Protobuf, + // GOOGLE_PROTOBUF_VERSION will have a different value. + if (GOOGLE_PROTOBUF_VERSION != protobufVersionCompiledWith) { ABSL_LOG(FATAL) - << "This program requires version " << VersionString(minLibraryVersion) - << " of the Protocol Buffer runtime library, but the installed version " - "is " + << "This program was compiled with Protobuf C++ version " + << VersionString(protobufVersionCompiledWith) + << ", but the linked version is " << VersionString(GOOGLE_PROTOBUF_VERSION) - << ". Please update " - "your library. If you compiled the program yourself, make sure " - "that " + << ". Please update your library. If you compiled the program " + "yourself, make sure that" "your headers are from the same version of Protocol Buffers as your " "link-time library. (Version verification failed in \"" << filename << "\".)"; } - if (headerVersion < kMinHeaderVersionForLibrary) { - // Headers are too old for library. - ABSL_LOG(FATAL) - << "This program was compiled against version " - << VersionString(headerVersion) - << " of the Protocol Buffer runtime " - "library, which is not compatible with the installed version (" - << VersionString(GOOGLE_PROTOBUF_VERSION) - << "). Contact the program " - "author for an update. If you compiled the program yourself, make " - "sure that your headers are from the same version of Protocol " - "Buffers " - "as your link-time library. (Version verification failed in \"" - << filename << "\".)"; - } } std::string VersionString(int version) { diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index 5eb0df4c02..459bd15d16 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h @@ -13,6 +13,7 @@ #define GOOGLE_PROTOBUF_COMMON_H__ #include +#include #include #include #include @@ -44,27 +45,14 @@ namespace internal { // The current version, represented as a single integer to make comparison // easier: major * 10^6 + minor * 10^3 + micro -#define GOOGLE_PROTOBUF_VERSION 4024000 +#define GOOGLE_PROTOBUF_VERSION 4026000 // A suffix string for alpha, beta or rc releases. Empty for stable releases. #define GOOGLE_PROTOBUF_VERSION_SUFFIX "" -// The minimum header version which works with the current version of -// the library. This constant should only be used by protoc's C++ code -// generator. -static const int kMinHeaderVersionForLibrary = 4024000; - -// The minimum protoc version which works with the current version of the -// headers. -#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 4024000 - -// The minimum header version which works with the current version of -// protoc. This constant should only be used in VerifyVersion(). -static const int kMinHeaderVersionForProtoc = 4024000; - -// Verifies that the headers and libraries are compatible. Use the macro -// below to call this. -void PROTOBUF_EXPORT VerifyVersion(int headerVersion, int minLibraryVersion, +// Verifies that the protobuf version a program was compiled with matches what +// it is linked/running with. Use the macro below to call this function. +void PROTOBUF_EXPORT VerifyVersion(int protobufVersionCompiledWith, const char* filename); // Converts a numeric version number to a string. @@ -81,9 +69,8 @@ ProtocVersionString(int version); // NOLINT(runtime/string) // to use the protobuf library) to verify that the version you link against // matches the headers you compiled against. If a version mismatch is // detected, the process will abort. -#define GOOGLE_PROTOBUF_VERIFY_VERSION \ - ::google::protobuf::internal::VerifyVersion( \ - GOOGLE_PROTOBUF_VERSION, GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION, __FILE__) +#define GOOGLE_PROTOBUF_VERIFY_VERSION \ + ::google::protobuf::internal::VerifyVersion(GOOGLE_PROTOBUF_VERSION, __FILE__) // This lives in message_lite.h now, but we leave this here for any users that // #include common.h and not message_lite.h. diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index 9abd84772a..591543c903 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,7 @@ #include "google/protobuf/repeated_field.h" #include "google/protobuf/unknown_field_set.h" #include "google/protobuf/wire_format_lite.h" +#include "utf8_validity.h" // Must be included last. #include "google/protobuf/port_def.inc" @@ -295,6 +297,14 @@ const Descriptor* DefaultFinderFindAnyType(const Message& message, } } // namespace +const void* TextFormat::Parser::UnsetFieldsMetadata::GetUnsetFieldAddress( + const Message& message, const Reflection& reflection, + const FieldDescriptor& fd) { + // reflection->GetRaw() is a simple cast for any non-repeated type, so for + // simplicity we just pass in char as the template argument. + return &reflection.GetRaw(message, &fd); +} + // =========================================================================== // Internal class for parsing an ASCII representation of a Protocol Message. // This class makes use of the Protocol Message compiler's tokenizer found @@ -331,7 +341,7 @@ class TextFormat::Parser::ParserImpl { bool allow_unknown_extension, bool allow_unknown_enum, bool allow_field_number, bool allow_relaxed_whitespace, bool allow_partial, int recursion_limit, - bool error_on_no_op_fields) + UnsetFieldsMetadata* no_op_fields) : error_collector_(error_collector), finder_(finder), parse_info_tree_(parse_info_tree), @@ -349,7 +359,7 @@ class TextFormat::Parser::ParserImpl { recursion_limit_(recursion_limit), had_silent_marker_(false), had_errors_(false), - error_on_no_op_fields_(error_on_no_op_fields) { + no_op_fields_(no_op_fields) { // For backwards-compatibility with proto1, we need to allow the 'f' suffix // for floats. tokenizer_.set_allow_f_after_float(true); @@ -834,19 +844,21 @@ class TextFormat::Parser::ParserImpl { // When checking for no-op operations, We verify that both the existing value in // the message and the new value are the default. If the existing field value is // not the default, setting it to the default should not be treated as a no-op. -#define SET_FIELD(CPPTYPE, CPPTYPELCASE, VALUE) \ - if (field->is_repeated()) { \ - reflection->Add##CPPTYPE(message, field, VALUE); \ - } else { \ - if (error_on_no_op_fields_ && !field->has_presence() && \ - field->default_value_##CPPTYPELCASE() == \ - reflection->Get##CPPTYPE(*message, field) && \ - field->default_value_##CPPTYPELCASE() == VALUE) { \ - ReportError("Input field " + field->full_name() + \ - " did not change resulting proto."); \ - } else { \ - reflection->Set##CPPTYPE(message, field, std::move(VALUE)); \ - } \ +// The pointer of this is kept in no_op_fields_ for bookkeeping. +#define SET_FIELD(CPPTYPE, CPPTYPELCASE, VALUE) \ + if (field->is_repeated()) { \ + reflection->Add##CPPTYPE(message, field, VALUE); \ + } else { \ + if (no_op_fields_ && !field->has_presence() && \ + field->default_value_##CPPTYPELCASE() == \ + reflection->Get##CPPTYPE(*message, field) && \ + field->default_value_##CPPTYPELCASE() == VALUE) { \ + no_op_fields_->addresses_.insert( \ + UnsetFieldsMetadata::GetUnsetFieldAddress(*message, *reflection, \ + *field)); \ + } else { \ + reflection->Set##CPPTYPE(message, field, std::move(VALUE)); \ + } \ } switch (field->cpp_type()) { @@ -1429,7 +1441,7 @@ class TextFormat::Parser::ParserImpl { int recursion_limit_; bool had_silent_marker_; bool had_errors_; - bool error_on_no_op_fields_; + UnsetFieldsMetadata* no_op_fields_{}; }; @@ -1637,6 +1649,83 @@ class TextFormat::Printer::DebugStringFieldValuePrinter } }; +namespace { + +// Returns true if `ch` needs to be escaped in TextFormat, independent of any +// UTF-8 validity issues. +bool DefinitelyNeedsEscape(unsigned char ch) { + if (ch < 32) return true; + switch (ch) { + case '\"': + case '\'': + case '\\': + return true; + } + return false; +} + +// Returns true if this is a high byte that requires UTF-8 validation. If the +// UTF-8 validation fails, we must escape the byte. +bool NeedsUtf8Validation(unsigned char ch) { return ch > 127; } + +// Returns the number of bytes in the prefix of `val` that do not need escaping. +// This is like utf8_range::SpanStructurallyValid(), except that it also +// terminates at any ASCII char that needs to be escaped in TextFormat (any char +// that has `DefinitelyNeedsEscape(ch) == true`). +// +// If we could get a variant of utf8_range::SpanStructurallyValid() that could +// terminate on any of these chars, that might be more efficient, but it would +// be much more complicated to modify that heavily SIMD code. +size_t SkipPassthroughBytes(absl::string_view val) { + for (size_t i = 0; i < val.size(); i++) { + unsigned char uc = val[i]; + if (DefinitelyNeedsEscape(uc)) return i; + if (NeedsUtf8Validation(uc)) { + // Find the end of this region of consecutive high bytes, so that we only + // give high bytes to the UTF-8 checker. This avoids needing to perform + // a second scan of the ASCII characters looking for characters that + // need escaping. + // + // We assume that high bytes are less frequent than plain, printable ASCII + // bytes, so we accept the double-scan of high bytes. + size_t end = i + 1; + for (; end < val.size(); end++) { + if (!NeedsUtf8Validation(val[end])) break; + } + size_t n = end - i; + size_t ok = utf8_range::SpanStructurallyValid(val.substr(i, n)); + if (ok != n) return i + ok; + i += ok - 1; + } + } + return val.size(); +} + +void HardenedPrintString(absl::string_view src, + TextFormat::BaseTextGenerator* generator) { + // Print as UTF-8, while guarding against any invalid UTF-8 in the string + // field. + // + // If in the future we have a guaranteed invariant that invalid UTF-8 will + // never be present, we could avoid the UTF-8 check here. + + while (!src.empty()) { + size_t n = SkipPassthroughBytes(src); + if (n != 0) { + generator->PrintString(src.substr(0, n)); + src.remove_prefix(n); + if (src.empty()) break; + } + + // If repeated calls to CEscape() and PrintString() are expensive, we could + // consider batching them, at the cost of some complexity. + generator->PrintString(absl::CEscape(src.substr(0, 1))); + src.remove_prefix(1); + } +} + +} // namespace + // =========================================================================== // An internal field value printer that escape UTF8 strings. class TextFormat::Printer::FastFieldValuePrinterUtf8Escaping @@ -1645,7 +1734,7 @@ class TextFormat::Printer::FastFieldValuePrinterUtf8Escaping void PrintString(const std::string& val, TextFormat::BaseTextGenerator* generator) const override { generator->PrintLiteral("\""); - generator->PrintString(absl::Utf8SafeCEscape(val)); + HardenedPrintString(val, generator); generator->PrintLiteral("\""); } void PrintBytes(const std::string& val, @@ -1727,7 +1816,7 @@ bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input, allow_case_insensitive_field_, allow_unknown_field_, allow_unknown_extension_, allow_unknown_enum_, allow_field_number_, allow_relaxed_whitespace_, - allow_partial_, recursion_limit_, error_on_no_op_fields_); + allow_partial_, recursion_limit_, no_op_fields_); return MergeUsingImpl(input, output, &parser); } @@ -1752,7 +1841,7 @@ bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, allow_case_insensitive_field_, allow_unknown_field_, allow_unknown_extension_, allow_unknown_enum_, allow_field_number_, allow_relaxed_whitespace_, - allow_partial_, recursion_limit_, error_on_no_op_fields_); + allow_partial_, recursion_limit_, no_op_fields_); return MergeUsingImpl(input, output, &parser); } @@ -1788,7 +1877,7 @@ bool TextFormat::Parser::ParseFieldValueFromString(absl::string_view input, allow_case_insensitive_field_, allow_unknown_field_, allow_unknown_extension_, allow_unknown_enum_, allow_field_number_, allow_relaxed_whitespace_, - allow_partial_, recursion_limit_, error_on_no_op_fields_); + allow_partial_, recursion_limit_, no_op_fields_); return parser.ParseField(field, output); } @@ -1946,7 +2035,9 @@ void TextFormat::FastFieldValuePrinter::PrintEnum( void TextFormat::FastFieldValuePrinter::PrintString( const std::string& val, BaseTextGenerator* generator) const { generator->PrintLiteral("\""); - generator->PrintString(absl::CEscape(val)); + if (!val.empty()) { + generator->PrintString(absl::CEscape(val)); + } generator->PrintLiteral("\""); } void TextFormat::FastFieldValuePrinter::PrintBytes( diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h index f851c910f8..f80aefb713 100644 --- a/src/google/protobuf/text_format.h +++ b/src/google/protobuf/text_format.h @@ -21,6 +21,7 @@ #include #include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" #include "absl/strings/cord.h" #include "absl/strings/string_view.h" #include "google/protobuf/descriptor.h" @@ -65,7 +66,10 @@ PROTOBUF_EXPORT enum class FieldReporterLevel { kUtf8Format = 8, kDebugString = 12, kShortDebugString = 13, - kUtf8DebugString = 14 + kUtf8DebugString = 14, + kUnredactedDebugFormatForTest = 15, + kUnredactedShortDebugFormatForTest = 16, + kUnredactedUtf8DebugFormatForTest = 17 }; } // namespace internal @@ -81,6 +85,9 @@ PROTOBUF_EXPORT enum class Option; // Converts a protobuf message to a string with redaction enabled. PROTOBUF_EXPORT std::string StringifyMessage(const Message& message, Option option); + +class UnsetFieldsMetadataTextFormatTestUtil; +class UnsetFieldsMetadataMessageDifferencerTestUtil; } // namespace internal // This class implements protocol buffer text format, colloquially known as text @@ -719,11 +726,40 @@ class PROTOBUF_EXPORT TextFormat { // the maximum allowed nesting of proto messages. void SetRecursionLimit(int limit) { recursion_limit_ = limit; } - // If called, the parser will report an error if a parsed field had no + // Uniquely addresses fields in a message that was explicitly unset in + // textproto. Example: + // "some_int_field: 0" + // where some_int_field is non-optional. + // + // This class should only be used to pass data between the text_format + // parser and the MessageDifferencer. + class UnsetFieldsMetadata { + public: + UnsetFieldsMetadata() = default; + + private: + // Return a pointer to the unset field in the given message. + static const void* GetUnsetFieldAddress(const Message& message, + const Reflection& reflection, + const FieldDescriptor& fd); + + // List of addresses of explicitly unset proto fields. + absl::flat_hash_set addresses_; + + friend class ::google::protobuf::internal:: + UnsetFieldsMetadataMessageDifferencerTestUtil; + friend class ::google::protobuf::internal::UnsetFieldsMetadataTextFormatTestUtil; + friend class ::google::protobuf::util::MessageDifferencer; + friend class ::google::protobuf::TextFormat::Parser; + }; + + // If called, the parser will report the parsed fields that had no // effect on the resulting proto (for example, fields with no presence that - // were set to their default value). - void ErrorOnNoOpFields(bool return_error) { - error_on_no_op_fields_ = return_error; + // were set to their default value). These can be passed to the Partially() + // matcher as an indicator to explicitly check these fields are missing + // in the actual. + void OutputNoOpFields(UnsetFieldsMetadata* no_op_fields) { + no_op_fields_ = no_op_fields; } private: @@ -748,7 +784,7 @@ class PROTOBUF_EXPORT TextFormat { bool allow_relaxed_whitespace_; bool allow_singular_overwrites_; int recursion_limit_; - bool error_on_no_op_fields_ = false; + UnsetFieldsMetadata* no_op_fields_ = nullptr; }; diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index 9f60c9f3fd..c3b3fd29ba 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -15,9 +15,11 @@ #include #include +#include #include #include #include +#include #include "google/protobuf/testing/file.h" #include "google/protobuf/testing/file.h" @@ -34,6 +36,7 @@ #include "absl/strings/str_format.h" #include "absl/strings/str_replace.h" #include "absl/strings/substitute.h" +#include "google/protobuf/descriptor.h" #include "google/protobuf/io/tokenizer.h" #include "google/protobuf/io/zero_copy_stream_impl.h" #include "google/protobuf/map_unittest.pb.h" @@ -44,6 +47,7 @@ #include "google/protobuf/unittest_mset.pb.h" #include "google/protobuf/unittest_mset_wire_format.pb.h" #include "google/protobuf/unittest_proto3.pb.h" +#include "utf8_validity.h" // Must be included last. @@ -52,10 +56,33 @@ namespace google { namespace protobuf { +namespace internal { +class UnsetFieldsMetadataTextFormatTestUtil { + public: + static std::vector GetRawAddresses( + const TextFormat::Parser::UnsetFieldsMetadata& metadata) { + return std::vector(metadata.addresses_.begin(), + metadata.addresses_.end()); + } + static const void* GetAddress(const Message& message, + const Reflection& reflection, + const FieldDescriptor& fd) { + return TextFormat::Parser::UnsetFieldsMetadata::GetUnsetFieldAddress( + message, reflection, fd); + } + + static int32_t NumFields( + const TextFormat::Parser::UnsetFieldsMetadata& metadata) { + return metadata.addresses_.size(); + } +}; +} // namespace internal + // Can't use an anonymous namespace here due to brokenness of Tru64 compiler. namespace text_format_unittest { using ::google::protobuf::internal::kDebugStringSilentMarker; +using ::google::protobuf::internal::UnsetFieldsMetadataTextFormatTestUtil; using ::testing::AllOf; using ::testing::HasSubstr; @@ -997,86 +1024,207 @@ TEST_F(TextFormatTest, ParseUnknownEnumFieldProto3) { EXPECT_EQ(-2147483648, proto.repeated_nested_enum(3)); } -TEST_F(TextFormatTest, ErrorOnNoOpFieldsProto3) { +TEST_F(TextFormatTest, PopulatesNoOpFields) { proto3_unittest::TestAllTypes proto; TextFormat::Parser parser; - parser.ErrorOnNoOpFields(true); + TextFormat::Parser::UnsetFieldsMetadata no_op_fields; + parser.OutputNoOpFields(&no_op_fields); { + no_op_fields = {}; const absl::string_view singular_int_parse_string = "optional_int32: 0"; EXPECT_TRUE(TextFormat::ParseFromString(singular_int_parse_string, &proto)); - EXPECT_FALSE(parser.ParseFromString(singular_int_parse_string, &proto)); + EXPECT_TRUE(parser.ParseFromString(singular_int_parse_string, &proto)); + EXPECT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 1); } { + no_op_fields = {}; const absl::string_view singular_bool_parse_string = "optional_bool: false"; EXPECT_TRUE( TextFormat::ParseFromString(singular_bool_parse_string, &proto)); - EXPECT_FALSE(parser.ParseFromString(singular_bool_parse_string, &proto)); + EXPECT_TRUE(parser.ParseFromString(singular_bool_parse_string, &proto)); + EXPECT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 1); } { + no_op_fields = {}; const absl::string_view singular_string_parse_string = "optional_string: ''"; EXPECT_TRUE( TextFormat::ParseFromString(singular_string_parse_string, &proto)); - EXPECT_FALSE(parser.ParseFromString(singular_string_parse_string, &proto)); + EXPECT_TRUE(parser.ParseFromString(singular_string_parse_string, &proto)); + EXPECT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 1); } { + no_op_fields = {}; const absl::string_view nested_message_parse_string = "optional_nested_message { bb: 0 } "; EXPECT_TRUE( TextFormat::ParseFromString(nested_message_parse_string, &proto)); - EXPECT_FALSE(parser.ParseFromString(nested_message_parse_string, &proto)); + EXPECT_TRUE(parser.ParseFromString(nested_message_parse_string, &proto)); + EXPECT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 1); + } + { + no_op_fields = {}; + const absl::string_view nested_message_parse_string = + "optional_nested_message { bb: 1 } "; + EXPECT_TRUE( + TextFormat::ParseFromString(nested_message_parse_string, &proto)); + EXPECT_TRUE(parser.ParseFromString(nested_message_parse_string, &proto)); + EXPECT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 0); } { + no_op_fields = {}; const absl::string_view foreign_message_parse_string = "optional_foreign_message { c: 0 } "; EXPECT_TRUE( TextFormat::ParseFromString(foreign_message_parse_string, &proto)); - EXPECT_FALSE(parser.ParseFromString(foreign_message_parse_string, &proto)); + EXPECT_TRUE(parser.ParseFromString(foreign_message_parse_string, &proto)); + EXPECT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 1); } { + no_op_fields = {}; const absl::string_view nested_enum_parse_string = "optional_nested_enum: ZERO "; EXPECT_TRUE(TextFormat::ParseFromString(nested_enum_parse_string, &proto)); - EXPECT_FALSE(parser.ParseFromString(nested_enum_parse_string, &proto)); + EXPECT_TRUE(parser.ParseFromString(nested_enum_parse_string, &proto)); + EXPECT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 1); } { + no_op_fields = {}; const absl::string_view foreign_enum_parse_string = "optional_foreign_enum: FOREIGN_ZERO "; EXPECT_TRUE(TextFormat::ParseFromString(foreign_enum_parse_string, &proto)); - EXPECT_FALSE(parser.ParseFromString(foreign_enum_parse_string, &proto)); + EXPECT_TRUE(parser.ParseFromString(foreign_enum_parse_string, &proto)); + EXPECT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 1); } { + no_op_fields = {}; const absl::string_view string_piece_parse_string = "optional_string_piece: '' "; EXPECT_TRUE(TextFormat::ParseFromString(string_piece_parse_string, &proto)); - EXPECT_FALSE(parser.ParseFromString(string_piece_parse_string, &proto)); + EXPECT_TRUE(parser.ParseFromString(string_piece_parse_string, &proto)); + EXPECT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 1); } { + no_op_fields = {}; const absl::string_view cord_parse_string = "optional_cord: '' "; EXPECT_TRUE(TextFormat::ParseFromString(cord_parse_string, &proto)); - EXPECT_FALSE(parser.ParseFromString(cord_parse_string, &proto)); + EXPECT_TRUE(parser.ParseFromString(cord_parse_string, &proto)); + EXPECT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 1); } { + no_op_fields = {}; // Sanity check that repeated fields work the same. const absl::string_view repeated_int32_parse_string = "repeated_int32: 0 "; EXPECT_TRUE( TextFormat::ParseFromString(repeated_int32_parse_string, &proto)); EXPECT_TRUE(parser.ParseFromString(repeated_int32_parse_string, &proto)); + EXPECT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 0); } { + no_op_fields = {}; const absl::string_view repeated_bool_parse_string = "repeated_bool: false "; EXPECT_TRUE( TextFormat::ParseFromString(repeated_bool_parse_string, &proto)); EXPECT_TRUE(parser.ParseFromString(repeated_bool_parse_string, &proto)); + EXPECT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 0); } { + no_op_fields = {}; const absl::string_view repeated_string_parse_string = "repeated_string: '' "; EXPECT_TRUE( TextFormat::ParseFromString(repeated_string_parse_string, &proto)); EXPECT_TRUE(parser.ParseFromString(repeated_string_parse_string, &proto)); + EXPECT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 0); + } +} + +TEST_F(TextFormatTest, FieldsPopulatedCorrectly) { + proto3_unittest::TestAllTypes proto; + TextFormat::Parser parser; + TextFormat::Parser::UnsetFieldsMetadata no_op_fields; + parser.OutputNoOpFields(&no_op_fields); + { + no_op_fields = {}; + const absl::string_view parse_string = R"pb( + optional_int32: 0 + optional_uint32: 10 + optional_nested_message { bb: 0 } + )pb"; + EXPECT_TRUE(parser.ParseFromString(parse_string, &proto)); + ASSERT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 2); + std::vector ptrs = + UnsetFieldsMetadataTextFormatTestUtil::GetRawAddresses(no_op_fields); + EXPECT_EQ(*static_cast(ptrs[0]), 0); + EXPECT_EQ(*static_cast(ptrs[1]), 0); + proto.set_optional_int32(20); + proto.mutable_optional_nested_message()->set_bb(30); + const std::vector new_values{ + *static_cast(ptrs[0]), + *static_cast(ptrs[1])}; + EXPECT_THAT(new_values, testing::UnorderedElementsAre(20, 30)); + } + { + no_op_fields = {}; + const absl::string_view parse_string = R"pb( + optional_bool: false + optional_uint32: 10 + optional_nested_message { bb: 20 } + )pb"; + EXPECT_TRUE(parser.ParseFromString(parse_string, &proto)); + ASSERT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 1); + std::vector ptrs = + UnsetFieldsMetadataTextFormatTestUtil::GetRawAddresses(no_op_fields); + EXPECT_EQ(*static_cast(ptrs[0]), false); + proto.set_optional_bool(true); + EXPECT_EQ(*static_cast(ptrs[0]), true); + } + { + // The address returned by the field is a string_view, which is a separate + // alocation. Check address directly. + no_op_fields = {}; + const absl::string_view parse_string = "optional_string: \"\""; + EXPECT_TRUE(parser.ParseFromString(parse_string, &proto)); + ASSERT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 1); + const Reflection* reflection = proto.GetReflection(); + const FieldDescriptor* field = proto.GetDescriptor()->FindFieldByNumber(14); + EXPECT_EQ( + UnsetFieldsMetadataTextFormatTestUtil::GetRawAddresses(no_op_fields)[0], + UnsetFieldsMetadataTextFormatTestUtil::GetAddress(proto, *reflection, + *field)); + } + { + // The address returned by the field is a string_view, which is a separate + // alocation. Check address directly. + no_op_fields = {}; + const absl::string_view parse_string = "optional_bytes: \"\""; + EXPECT_TRUE(parser.ParseFromString(parse_string, &proto)); + ASSERT_EQ(UnsetFieldsMetadataTextFormatTestUtil::NumFields(no_op_fields), + 1); + const Reflection* reflection = proto.GetReflection(); + const FieldDescriptor* field = proto.GetDescriptor()->FindFieldByNumber(15); + EXPECT_EQ( + UnsetFieldsMetadataTextFormatTestUtil::GetRawAddresses(no_op_fields)[0], + UnsetFieldsMetadataTextFormatTestUtil::GetAddress(proto, *reflection, + *field)); } } diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc index e048cb8c30..c8beb68e13 100644 --- a/src/google/protobuf/timestamp.pb.cc +++ b/src/google/protobuf/timestamp.pb.cc @@ -1,5 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/timestamp.proto +// Protobuf C++ Version: 4.26.0-dev #include "google/protobuf/timestamp.pb.h" @@ -114,9 +115,6 @@ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2ftimestamp_2ep PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2ftimestamp_2eproto; } -// Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 -static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2ftimestamp_2eproto(&descriptor_table_google_2fprotobuf_2ftimestamp_2eproto); namespace google { namespace protobuf { // =================================================================== @@ -162,12 +160,13 @@ inline void Timestamp::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* Timestamp::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { Timestamp::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(Timestamp, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void Timestamp::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Timestamp) @@ -203,6 +202,9 @@ const ::_pbi::TcParseTable<1, 2, 0, 0, 2> Timestamp::_table_ = { offsetof(decltype(_table_), field_names), // no aux_entries &_Timestamp_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::Timestamp>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // int32 nanos = 2; {::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(Timestamp, _impl_.nanos_), 63>(), @@ -279,7 +281,7 @@ const ::_pbi::TcParseTable<1, 2, 0, 0, 2> Timestamp::_table_ = { } -void Timestamp::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void Timestamp::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Timestamp) @@ -288,10 +290,10 @@ void Timestamp::MergeImpl(::google::protobuf::Message& to_msg, const ::google::p (void) cached_has_bits; if (from._internal_seconds() != 0) { - _this->_internal_set_seconds(from._internal_seconds()); + _this->_impl_.seconds_ = from._impl_.seconds_; } if (from._internal_nanos() != 0) { - _this->_internal_set_nanos(from._internal_nanos()); + _this->_impl_.nanos_ = from._impl_.nanos_; } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -307,9 +309,6 @@ PROTOBUF_NOINLINE bool Timestamp::IsInitialized() const { return true; } -::_pbi::CachedSize* Timestamp::AccessCachedSize() const { - return &_impl_._cached_size_; -} void Timestamp::InternalSwap(Timestamp* PROTOBUF_RESTRICT other) { using std::swap; _internal_metadata_.InternalSwap(&other->_internal_metadata_); @@ -322,9 +321,9 @@ void Timestamp::InternalSwap(Timestamp* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata Timestamp::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_once, - file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto[0]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_getter, + &descriptor_table_google_2fprotobuf_2ftimestamp_2eproto_once, + file_level_metadata_google_2fprotobuf_2ftimestamp_2eproto[0]); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf @@ -334,4 +333,8 @@ namespace protobuf { } // namespace protobuf } // namespace google // @@protoc_insertion_point(global_scope) +PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 +static ::std::false_type _static_init_ PROTOBUF_UNUSED = + (::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2ftimestamp_2eproto), + ::std::false_type{}); #include "google/protobuf/port_undef.inc" diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h index 8c1d97196e..e987282c60 100644 --- a/src/google/protobuf/timestamp.pb.h +++ b/src/google/protobuf/timestamp.pb.h @@ -1,6 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/timestamp.proto -// Protobuf C++ Version: 4.24.0-main +// Protobuf C++ Version: 4.26.0-dev #ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftimestamp_2eproto_2epb_2eh #define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2ftimestamp_2eproto_2epb_2eh @@ -11,17 +11,11 @@ #include #include "google/protobuf/port_def.inc" -#if PROTOBUF_VERSION < 4024000 -#error "This file was generated by a newer version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please update" -#error "your headers." -#endif // PROTOBUF_VERSION - -#if 4024000 < PROTOBUF_MIN_PROTOC_VERSION -#error "This file was generated by an older version of protoc which is" -#error "incompatible with your Protocol Buffer headers. Please" -#error "regenerate this file with a newer version of protoc." -#endif // PROTOBUF_MIN_PROTOC_VERSION +#if PROTOBUF_VERSION != 4026000 +#error "Protobuf C++ gencode is built with an incompatible version of" +#error "Protobuf C++ headers/runtime. See" +#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp" +#endif #include "google/protobuf/port_undef.inc" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/arena.h" @@ -71,21 +65,18 @@ namespace protobuf { // ------------------------------------------------------------------- -class PROTOBUF_EXPORT Timestamp final : - public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.Timestamp) */ { +class PROTOBUF_EXPORT Timestamp final : public ::google::protobuf::Message +/* @@protoc_insertion_point(class_definition:google.protobuf.Timestamp) */ { public: inline Timestamp() : Timestamp(nullptr) {} ~Timestamp() override; - template - explicit PROTOBUF_CONSTEXPR Timestamp(::google::protobuf::internal::ConstantInitialized); - - inline Timestamp(const Timestamp& from) - : Timestamp(nullptr, from) {} - Timestamp(Timestamp&& from) noexcept - : Timestamp() { - *this = ::std::move(from); - } + template + explicit PROTOBUF_CONSTEXPR Timestamp( + ::google::protobuf::internal::ConstantInitialized); + inline Timestamp(const Timestamp& from) : Timestamp(nullptr, from) {} + inline Timestamp(Timestamp&& from) noexcept + : Timestamp(nullptr, std::move(from)) {} inline Timestamp& operator=(const Timestamp& from) { CopyFrom(from); return *this; @@ -93,9 +84,9 @@ class PROTOBUF_EXPORT Timestamp final : inline Timestamp& operator=(Timestamp&& from) noexcept { if (this == &from) return *this; if (GetArena() == from.GetArena() - #ifdef PROTOBUF_FORCE_COPY_IN_MOVE +#ifdef PROTOBUF_FORCE_COPY_IN_MOVE && GetArena() != nullptr - #endif // !PROTOBUF_FORCE_COPY_IN_MOVE +#endif // !PROTOBUF_FORCE_COPY_IN_MOVE ) { InternalSwap(&from); } else { @@ -127,22 +118,17 @@ class PROTOBUF_EXPORT Timestamp final : } static inline const Timestamp* internal_default_instance() { return reinterpret_cast( - &_Timestamp_default_instance_); - } - static constexpr int kIndexInFileMessages = - 0; - - friend void swap(Timestamp& a, Timestamp& b) { - a.Swap(&b); + &_Timestamp_default_instance_); } + static constexpr int kIndexInFileMessages = 0; + friend void swap(Timestamp& a, Timestamp& b) { a.Swap(&b); } inline void Swap(Timestamp* other) { if (other == this) return; - #ifdef PROTOBUF_FORCE_COPY_IN_SWAP - if (GetArena() != nullptr && - GetArena() == other->GetArena()) { - #else // PROTOBUF_FORCE_COPY_IN_SWAP +#ifdef PROTOBUF_FORCE_COPY_IN_SWAP + if (GetArena() != nullptr && GetArena() == other->GetArena()) { +#else // PROTOBUF_FORCE_COPY_IN_SWAP if (GetArena() == other->GetArena()) { - #endif // !PROTOBUF_FORCE_COPY_IN_SWAP +#endif // !PROTOBUF_FORCE_COPY_IN_SWAP InternalSwap(other); } else { ::google::protobuf::internal::GenericSwap(this, other); @@ -157,16 +143,18 @@ class PROTOBUF_EXPORT Timestamp final : // implements Message ---------------------------------------------- Timestamp* New(::google::protobuf::Arena* arena = nullptr) const final { - return CreateMaybeMessage(arena); + return ::google::protobuf::Message::DefaultConstruct(arena); } using ::google::protobuf::Message::CopyFrom; void CopyFrom(const Timestamp& from); using ::google::protobuf::Message::MergeFrom; - void MergeFrom( const Timestamp& from) { - Timestamp::MergeImpl(*this, from); - } + void MergeFrom(const Timestamp& from) { Timestamp::MergeImpl(*this, from); } + private: - static void MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg); + static void MergeImpl( + ::google::protobuf::MessageLite& to_msg, + const ::google::protobuf::MessageLite& from_msg); + public: ABSL_ATTRIBUTE_REINITIALIZES void Clear() final; bool IsInitialized() const final; @@ -174,32 +162,33 @@ class PROTOBUF_EXPORT Timestamp final : ::size_t ByteSizeLong() const final; const char* _InternalParse(const char* ptr, ::google::protobuf::internal::ParseContext* ctx) final; ::uint8_t* _InternalSerialize( - ::uint8_t* target, ::google::protobuf::io::EpsCopyOutputStream* stream) const final; + ::uint8_t* target, + ::google::protobuf::io::EpsCopyOutputStream* stream) const final; int GetCachedSize() const { return _impl_._cached_size_.Get(); } private: - ::google::protobuf::internal::CachedSize* AccessCachedSize() const final; void SharedCtor(::google::protobuf::Arena* arena); void SharedDtor(); void InternalSwap(Timestamp* other); - - private: + private: friend class ::google::protobuf::internal::AnyMetadata; - static ::absl::string_view FullMessageName() { - return "google.protobuf.Timestamp"; - } - protected: + static ::absl::string_view FullMessageName() { return "google.protobuf.Timestamp"; } + + protected: explicit Timestamp(::google::protobuf::Arena* arena); Timestamp(::google::protobuf::Arena* arena, const Timestamp& from); - const ::google::protobuf::MessageLite::ClassData* GetClassData() const final; - public: + Timestamp(::google::protobuf::Arena* arena, Timestamp&& from) noexcept + : Timestamp(arena) { + *this = ::std::move(from); + } + const ::google::protobuf::MessageLite::ClassData* GetClassData() + const final; + public: ::google::protobuf::Metadata GetMetadata() const final; - // nested types ---------------------------------------------------- // accessors ------------------------------------------------------- - enum : int { kSecondsFieldNumber = 1, kNanosFieldNumber = 2, @@ -227,7 +216,6 @@ class PROTOBUF_EXPORT Timestamp final : // @@protoc_insertion_point(class_scope:google.protobuf.Timestamp) private: class _Internal; - friend class ::google::protobuf::internal::TcParser; static const ::google::protobuf::internal::TcParseTable< 1, 2, 0, @@ -239,14 +227,13 @@ class PROTOBUF_EXPORT Timestamp final : friend class ::google::protobuf::Arena::InternalHelper; using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct PROTOBUF_EXPORT Impl_ { - - inline explicit constexpr Impl_( - ::google::protobuf::internal::ConstantInitialized) noexcept; - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena); - inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, - ::google::protobuf::Arena* arena, const Impl_& from); + struct Impl_ { + inline explicit constexpr Impl_( + ::google::protobuf::internal::ConstantInitialized) noexcept; + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena); + inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility, + ::google::protobuf::Arena* arena, const Impl_& from); ::int64_t seconds_; ::int32_t nanos_; mutable ::google::protobuf::internal::CachedSize _cached_size_; @@ -291,7 +278,6 @@ inline ::int64_t Timestamp::_internal_seconds() const { } inline void Timestamp::_internal_set_seconds(::int64_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.seconds_ = value; } @@ -314,7 +300,6 @@ inline ::int32_t Timestamp::_internal_nanos() const { } inline void Timestamp::_internal_set_nanos(::int32_t value) { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); - ; _impl_.nanos_ = value; } diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc index 29884227e7..feddb6f739 100644 --- a/src/google/protobuf/type.pb.cc +++ b/src/google/protobuf/type.pb.cc @@ -1,5 +1,6 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/type.proto +// Protobuf C++ Version: 4.26.0-dev #include "google/protobuf/type.pb.h" @@ -353,9 +354,6 @@ const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2ftype_2eproto PROTOBUF_ATTRIBUTE_WEAK const ::_pbi::DescriptorTable* descriptor_table_google_2fprotobuf_2ftype_2eproto_getter() { return &descriptor_table_google_2fprotobuf_2ftype_2eproto; } -// Force running AddDescriptors() at dynamic initialization time. -PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 -static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2ftype_2eproto(&descriptor_table_google_2fprotobuf_2ftype_2eproto); namespace google { namespace protobuf { const ::google::protobuf::EnumDescriptor* Field_Kind_descriptor() { @@ -433,15 +431,8 @@ class Type::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(Type, _impl_._has_bits_); - static const ::google::protobuf::SourceContext& source_context(const Type* msg); - static void set_has_source_context(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } }; -const ::google::protobuf::SourceContext& Type::_Internal::source_context(const Type* msg) { - return *msg->_impl_.source_context_; -} void Type::clear_source_context() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (_impl_.source_context_ != nullptr) _impl_.source_context_->Clear(); @@ -473,9 +464,9 @@ Type::Type( from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.source_context_ = (cached_has_bits & 0x00000001u) - ? CreateMaybeMessage<::google::protobuf::SourceContext>(arena, *from._impl_.source_context_) - : nullptr; + _impl_.source_context_ = (cached_has_bits & 0x00000001u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::SourceContext>( + arena, *from._impl_.source_context_) + : nullptr; _impl_.syntax_ = from._impl_.syntax_; // @@protoc_insertion_point(copy_constructor:google.protobuf.Type) @@ -515,12 +506,13 @@ inline void Type::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* Type::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { Type::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(Type, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void Type::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Type) @@ -565,6 +557,9 @@ const ::_pbi::TcParseTable<3, 7, 3, 46, 2> Type::_table_ = { offsetof(decltype(_table_), aux_entries), &_Type_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::Type>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // string name = 1; @@ -668,8 +663,7 @@ const ::_pbi::TcParseTable<3, 7, 3, 46, 2> Type::_table_ = { // .google.protobuf.SourceContext source_context = 5; if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 5, _Internal::source_context(this), - _Internal::source_context(this).GetCachedSize(), target, stream); + 5, *_impl_.source_context_, _impl_.source_context_->GetCachedSize(), target, stream); } // .google.protobuf.Syntax syntax = 6; @@ -751,9 +745,10 @@ const ::_pbi::TcParseTable<3, 7, 3, 46, 2> Type::_table_ = { } -void Type::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void Type::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Type) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -770,13 +765,20 @@ void Type::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protob if (!from._internal_edition().empty()) { _this->_internal_set_edition(from._internal_edition()); } - if ((from._impl_._has_bits_[0] & 0x00000001u) != 0) { - _this->_internal_mutable_source_context()->::google::protobuf::SourceContext::MergeFrom( - from._internal_source_context()); + cached_has_bits = from._impl_._has_bits_[0]; + if (cached_has_bits & 0x00000001u) { + ABSL_DCHECK(from._impl_.source_context_ != nullptr); + if (_this->_impl_.source_context_ == nullptr) { + _this->_impl_.source_context_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::SourceContext>(arena, *from._impl_.source_context_); + } else { + _this->_impl_.source_context_->MergeFrom(*from._impl_.source_context_); + } } if (from._internal_syntax() != 0) { - _this->_internal_set_syntax(from._internal_syntax()); + _this->_impl_.syntax_ = from._impl_.syntax_; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -791,9 +793,6 @@ PROTOBUF_NOINLINE bool Type::IsInitialized() const { return true; } -::_pbi::CachedSize* Type::AccessCachedSize() const { - return &_impl_._cached_size_; -} void Type::InternalSwap(Type* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -814,9 +813,9 @@ void Type::InternalSwap(Type* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata Type::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, - file_level_metadata_google_2fprotobuf_2ftype_2eproto[0]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, + &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, + file_level_metadata_google_2fprotobuf_2ftype_2eproto[0]); } // =================================================================== @@ -894,12 +893,13 @@ inline void Field::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* Field::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { Field::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(Field, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void Field::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Field) @@ -940,6 +940,9 @@ const ::_pbi::TcParseTable<4, 10, 1, 72, 2> Field::_table_ = { offsetof(decltype(_table_), aux_entries), &_Field_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::Field>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // .google.protobuf.Field.Kind kind = 1; @@ -1184,7 +1187,7 @@ const ::_pbi::TcParseTable<4, 10, 1, 72, 2> Field::_table_ = { } -void Field::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void Field::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Field) @@ -1207,19 +1210,19 @@ void Field::MergeImpl(::google::protobuf::Message& to_msg, const ::google::proto _this->_internal_set_default_value(from._internal_default_value()); } if (from._internal_kind() != 0) { - _this->_internal_set_kind(from._internal_kind()); + _this->_impl_.kind_ = from._impl_.kind_; } if (from._internal_cardinality() != 0) { - _this->_internal_set_cardinality(from._internal_cardinality()); + _this->_impl_.cardinality_ = from._impl_.cardinality_; } if (from._internal_number() != 0) { - _this->_internal_set_number(from._internal_number()); + _this->_impl_.number_ = from._impl_.number_; } if (from._internal_oneof_index() != 0) { - _this->_internal_set_oneof_index(from._internal_oneof_index()); + _this->_impl_.oneof_index_ = from._impl_.oneof_index_; } if (from._internal_packed() != 0) { - _this->_internal_set_packed(from._internal_packed()); + _this->_impl_.packed_ = from._impl_.packed_; } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -1235,9 +1238,6 @@ PROTOBUF_NOINLINE bool Field::IsInitialized() const { return true; } -::_pbi::CachedSize* Field::AccessCachedSize() const { - return &_impl_._cached_size_; -} void Field::InternalSwap(Field* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -1257,9 +1257,9 @@ void Field::InternalSwap(Field* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata Field::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, - file_level_metadata_google_2fprotobuf_2ftype_2eproto[1]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, + &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, + file_level_metadata_google_2fprotobuf_2ftype_2eproto[1]); } // =================================================================== @@ -1268,15 +1268,8 @@ class Enum::_Internal { using HasBits = decltype(std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(Enum, _impl_._has_bits_); - static const ::google::protobuf::SourceContext& source_context(const Enum* msg); - static void set_has_source_context(HasBits* has_bits) { - (*has_bits)[0] |= 1u; - } }; -const ::google::protobuf::SourceContext& Enum::_Internal::source_context(const Enum* msg) { - return *msg->_impl_.source_context_; -} void Enum::clear_source_context() { PROTOBUF_TSAN_WRITE(&_impl_._tsan_detect_race); if (_impl_.source_context_ != nullptr) _impl_.source_context_->Clear(); @@ -1307,9 +1300,9 @@ Enum::Enum( from._internal_metadata_); new (&_impl_) Impl_(internal_visibility(), arena, from._impl_); ::uint32_t cached_has_bits = _impl_._has_bits_[0]; - _impl_.source_context_ = (cached_has_bits & 0x00000001u) - ? CreateMaybeMessage<::google::protobuf::SourceContext>(arena, *from._impl_.source_context_) - : nullptr; + _impl_.source_context_ = (cached_has_bits & 0x00000001u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::SourceContext>( + arena, *from._impl_.source_context_) + : nullptr; _impl_.syntax_ = from._impl_.syntax_; // @@protoc_insertion_point(copy_constructor:google.protobuf.Enum) @@ -1348,12 +1341,13 @@ inline void Enum::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* Enum::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { Enum::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(Enum, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void Enum::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.Enum) @@ -1397,6 +1391,9 @@ const ::_pbi::TcParseTable<3, 6, 3, 40, 2> Enum::_table_ = { offsetof(decltype(_table_), aux_entries), &_Enum_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::Enum>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // string name = 1; @@ -1486,8 +1483,7 @@ const ::_pbi::TcParseTable<3, 6, 3, 40, 2> Enum::_table_ = { // .google.protobuf.SourceContext source_context = 4; if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage( - 4, _Internal::source_context(this), - _Internal::source_context(this).GetCachedSize(), target, stream); + 4, *_impl_.source_context_, _impl_.source_context_->GetCachedSize(), target, stream); } // .google.protobuf.Syntax syntax = 5; @@ -1563,9 +1559,10 @@ const ::_pbi::TcParseTable<3, 6, 3, 40, 2> Enum::_table_ = { } -void Enum::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void Enum::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); + ::google::protobuf::Arena* arena = _this->GetArena(); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Enum) ABSL_DCHECK_NE(&from, _this); ::uint32_t cached_has_bits = 0; @@ -1581,13 +1578,20 @@ void Enum::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protob if (!from._internal_edition().empty()) { _this->_internal_set_edition(from._internal_edition()); } - if ((from._impl_._has_bits_[0] & 0x00000001u) != 0) { - _this->_internal_mutable_source_context()->::google::protobuf::SourceContext::MergeFrom( - from._internal_source_context()); + cached_has_bits = from._impl_._has_bits_[0]; + if (cached_has_bits & 0x00000001u) { + ABSL_DCHECK(from._impl_.source_context_ != nullptr); + if (_this->_impl_.source_context_ == nullptr) { + _this->_impl_.source_context_ = + ::google::protobuf::Message::CopyConstruct<::google::protobuf::SourceContext>(arena, *from._impl_.source_context_); + } else { + _this->_impl_.source_context_->MergeFrom(*from._impl_.source_context_); + } } if (from._internal_syntax() != 0) { - _this->_internal_set_syntax(from._internal_syntax()); + _this->_impl_.syntax_ = from._impl_.syntax_; } + _this->_impl_._has_bits_[0] |= cached_has_bits; _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -1602,9 +1606,6 @@ PROTOBUF_NOINLINE bool Enum::IsInitialized() const { return true; } -::_pbi::CachedSize* Enum::AccessCachedSize() const { - return &_impl_._cached_size_; -} void Enum::InternalSwap(Enum* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -1624,9 +1625,9 @@ void Enum::InternalSwap(Enum* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata Enum::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, - file_level_metadata_google_2fprotobuf_2ftype_2eproto[2]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, + &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, + file_level_metadata_google_2fprotobuf_2ftype_2eproto[2]); } // =================================================================== @@ -1684,12 +1685,13 @@ inline void EnumValue::SharedDtor() { const ::google::protobuf::MessageLite::ClassData* EnumValue::GetClassData() const { PROTOBUF_CONSTINIT static const ::google::protobuf::MessageLite::ClassData - data = { + _data_ = { EnumValue::MergeImpl, nullptr, // OnDemandRegisterArenaDtor &::google::protobuf::Message::kDescriptorMethods, + PROTOBUF_FIELD_OFFSET(EnumValue, _impl_._cached_size_), }; - return &data; + return &_data_; } PROTOBUF_NOINLINE void EnumValue::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValue) @@ -1725,6 +1727,9 @@ const ::_pbi::TcParseTable<2, 3, 1, 38, 2> EnumValue::_table_ = { offsetof(decltype(_table_), aux_entries), &_EnumValue_default_instance_._instance, ::_pbi::TcParser::GenericFallback, // fallback + #ifdef PROTOBUF_PREFETCH_PARSE_TABLE + ::_pbi::TcParser::GetTable<::google::protobuf::EnumValue>(), // to_prefetch + #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // string name = 1; @@ -1826,7 +1831,7 @@ const ::_pbi::TcParseTable<2, 3, 1, 38, 2> EnumValue::_table_ = { } -void EnumValue::MergeImpl(::google::protobuf::Message& to_msg, const ::google::protobuf::Message& from_msg) { +void EnumValue::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) { auto* const _this = static_cast(&to_msg); auto& from = static_cast(from_msg); // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValue) @@ -1840,7 +1845,7 @@ void EnumValue::MergeImpl(::google::protobuf::Message& to_msg, const ::google::p _this->_internal_set_name(from._internal_name()); } if (from._internal_number() != 0) { - _this->_internal_set_number(from._internal_number()); + _this->_impl_.number_ = from._impl_.number_; } _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_); } @@ -1856,9 +1861,6 @@ PROTOBUF_NOINLINE bool EnumValue::IsInitialized() const { return true; } -::_pbi::CachedSize* EnumValue::AccessCachedSize() const { - return &_impl_._cached_size_; -} void EnumValue::InternalSwap(EnumValue* PROTOBUF_RESTRICT other) { using std::swap; auto* arena = GetArena(); @@ -1870,9 +1872,9 @@ void EnumValue::InternalSwap(EnumValue* PROTOBUF_RESTRICT other) { } ::google::protobuf::Metadata EnumValue::GetMetadata() const { - return ::_pbi::AssignDescriptors( - &descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, - file_level_metadata_google_2fprotobuf_2ftype_2eproto[3]); + return ::_pbi::AssignDescriptors(&descriptor_table_google_2fprotobuf_2ftype_2eproto_getter, + &descriptor_table_google_2fprotobuf_2ftype_2eproto_once, + file_level_metadata_google_2fprotobuf_2ftype_2eproto[3]); } // =================================================================== @@ -1881,15 +1883,8 @@ class Option::_Internal { using HasBits = decltype(std::declval